/*
 * QLogic qlcnic NIC Driver
 * Copyright (c) 2009-2013 QLogic Corporation
 *
 * See LICENSE.qlcnic for copyright and licensing details.
 */

#include <linux/types.h>

#include "qlcnic_sriov.h"
#include "qlcnic.h"
#include "qlcnic_83xx_hw.h"

#define QLC_BC_COMMAND	0
#define QLC_BC_RESPONSE	1

#define QLC_MBOX_RESP_TIMEOUT		(10 * HZ)
#define QLC_MBOX_CH_FREE_TIMEOUT	(10 * HZ)

#define QLC_BC_MSG		0
#define QLC_BC_CFREE		1
#define QLC_BC_FLR		2
#define QLC_BC_HDR_SZ		16
#define QLC_BC_PAYLOAD_SZ	(1024 - QLC_BC_HDR_SZ)

#define QLC_DEFAULT_RCV_DESCRIPTORS_SRIOV_VF		2048
#define QLC_DEFAULT_JUMBO_RCV_DESCRIPTORS_SRIOV_VF	512

#define QLC_83XX_VF_RESET_FAIL_THRESH	8
#define QLC_BC_CMD_MAX_RETRY_CNT	5

static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work);
static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *);
static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *, u32);
static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *);
static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *);
static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *);
static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *,
				  struct qlcnic_cmd_args *);
static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8);
static void qlcnic_sriov_process_bc_cmd(struct work_struct *);
static int qlcnic_sriov_vf_shutdown(struct pci_dev *);
static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *);
static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *,
					struct qlcnic_cmd_args *);

static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
	.read_crb			= qlcnic_83xx_read_crb,
	.write_crb			= qlcnic_83xx_write_crb,
	.read_reg			= qlcnic_83xx_rd_reg_indirect,
	.write_reg			= qlcnic_83xx_wrt_reg_indirect,
	.get_mac_address		= qlcnic_83xx_get_mac_address,
	.setup_intr			= qlcnic_83xx_setup_intr,
	.alloc_mbx_args			= qlcnic_83xx_alloc_mbx_args,
	.mbx_cmd			= qlcnic_sriov_issue_cmd,
	.get_func_no			= qlcnic_83xx_get_func_no,
	.api_lock			= qlcnic_83xx_cam_lock,
	.api_unlock			= qlcnic_83xx_cam_unlock,
	.process_lb_rcv_ring_diag	= qlcnic_83xx_process_rcv_ring_diag,
	.create_rx_ctx			= qlcnic_83xx_create_rx_ctx,
	.create_tx_ctx			= qlcnic_83xx_create_tx_ctx,
	.del_rx_ctx			= qlcnic_83xx_del_rx_ctx,
	.del_tx_ctx			= qlcnic_83xx_del_tx_ctx,
	.setup_link_event		= qlcnic_83xx_setup_link_event,
	.get_nic_info			= qlcnic_83xx_get_nic_info,
	.get_pci_info			= qlcnic_83xx_get_pci_info,
	.set_nic_info			= qlcnic_83xx_set_nic_info,
	.change_macvlan			= qlcnic_83xx_sre_macaddr_change,
	.napi_enable			= qlcnic_83xx_napi_enable,
	.napi_disable			= qlcnic_83xx_napi_disable,
	.config_intr_coal		= qlcnic_83xx_config_intr_coal,
	.config_rss			= qlcnic_83xx_config_rss,
	.config_hw_lro			= qlcnic_83xx_config_hw_lro,
	.config_promisc_mode		= qlcnic_83xx_nic_set_promisc,
	.change_l2_filter		= qlcnic_83xx_change_l2_filter,
	.get_board_info			= qlcnic_83xx_get_port_info,
	.free_mac_list			= qlcnic_sriov_vf_free_mac_list,
	.enable_sds_intr		= qlcnic_83xx_enable_sds_intr,
	.disable_sds_intr		= qlcnic_83xx_disable_sds_intr,
	.encap_rx_offload               = qlcnic_83xx_encap_rx_offload,
	.encap_tx_offload               = qlcnic_83xx_encap_tx_offload,
};

static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
	.config_bridged_mode	= qlcnic_config_bridged_mode,
	.config_led		= qlcnic_config_led,
	.cancel_idc_work        = qlcnic_sriov_vf_cancel_fw_work,
	.napi_add		= qlcnic_83xx_napi_add,
	.napi_del		= qlcnic_83xx_napi_del,
	.shutdown		= qlcnic_sriov_vf_shutdown,
	.resume			= qlcnic_sriov_vf_resume,
	.config_ipaddr		= qlcnic_83xx_config_ipaddr,
	.clear_legacy_intr	= qlcnic_83xx_clear_legacy_intr,
};

static const struct qlcnic_mailbox_metadata qlcnic_sriov_bc_mbx_tbl[] = {
	{QLCNIC_BC_CMD_CHANNEL_INIT, 2, 2},
	{QLCNIC_BC_CMD_CHANNEL_TERM, 2, 2},
	{QLCNIC_BC_CMD_GET_ACL, 3, 14},
	{QLCNIC_BC_CMD_CFG_GUEST_VLAN, 2, 2},
};

static inline bool qlcnic_sriov_bc_msg_check(u32 val)
{
	return (val & (1 << QLC_BC_MSG)) ? true : false;
}

static inline bool qlcnic_sriov_channel_free_check(u32 val)
{
	return (val & (1 << QLC_BC_CFREE)) ? true : false;
}

static inline bool qlcnic_sriov_flr_check(u32 val)
{
	return (val & (1 << QLC_BC_FLR)) ? true : false;
}

static inline u8 qlcnic_sriov_target_func_id(u32 val)
{
	return (val >> 4) & 0xff;
}

static int qlcnic_sriov_virtid_fn(struct qlcnic_adapter *adapter, int vf_id)
{
	struct pci_dev *dev = adapter->pdev;
	int pos;
	u16 stride, offset;

	if (qlcnic_sriov_vf_check(adapter))
		return 0;

	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
	if (!pos)
		return 0;
	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);

	return (dev->devfn + offset + stride * vf_id) & 0xff;
}

int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
{
	struct qlcnic_sriov *sriov;
	struct qlcnic_back_channel *bc;
	struct workqueue_struct *wq;
	struct qlcnic_vport *vp;
	struct qlcnic_vf_info *vf;
	int err, i;

	if (!qlcnic_sriov_enable_check(adapter))
		return -EIO;

	sriov  = kzalloc(sizeof(struct qlcnic_sriov), GFP_KERNEL);
	if (!sriov)
		return -ENOMEM;

	adapter->ahw->sriov = sriov;
	sriov->num_vfs = num_vfs;
	bc = &sriov->bc;
	sriov->vf_info = kcalloc(num_vfs, sizeof(struct qlcnic_vf_info),
				 GFP_KERNEL);
	if (!sriov->vf_info) {
		err = -ENOMEM;
		goto qlcnic_free_sriov;
	}

	wq = create_singlethread_workqueue("bc-trans");
	if (wq == NULL) {
		err = -ENOMEM;
		dev_err(&adapter->pdev->dev,
			"Cannot create bc-trans workqueue\n");
		goto qlcnic_free_vf_info;
	}

	bc->bc_trans_wq = wq;

	wq = create_singlethread_workqueue("async");
	if (wq == NULL) {
		err = -ENOMEM;
		dev_err(&adapter->pdev->dev, "Cannot create async workqueue\n");
		goto qlcnic_destroy_trans_wq;
	}

	bc->bc_async_wq =  wq;
	INIT_LIST_HEAD(&bc->async_cmd_list);
	INIT_WORK(&bc->vf_async_work, qlcnic_sriov_handle_async_issue_cmd);
	spin_lock_init(&bc->queue_lock);
	bc->adapter = adapter;

	for (i = 0; i < num_vfs; i++) {
		vf = &sriov->vf_info[i];
		vf->adapter = adapter;
		vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i);
		mutex_init(&vf->send_cmd_lock);
		spin_lock_init(&vf->vlan_list_lock);
		INIT_LIST_HEAD(&vf->rcv_act.wait_list);
		INIT_LIST_HEAD(&vf->rcv_pend.wait_list);
		spin_lock_init(&vf->rcv_act.lock);
		spin_lock_init(&vf->rcv_pend.lock);
		init_completion(&vf->ch_free_cmpl);

		INIT_WORK(&vf->trans_work, qlcnic_sriov_process_bc_cmd);

		if (qlcnic_sriov_pf_check(adapter)) {
			vp = kzalloc(sizeof(struct qlcnic_vport), GFP_KERNEL);
			if (!vp) {
				err = -ENOMEM;
				goto qlcnic_destroy_async_wq;
			}
			sriov->vf_info[i].vp = vp;
			vp->vlan_mode = QLC_GUEST_VLAN_MODE;
			vp->max_tx_bw = MAX_BW;
			vp->min_tx_bw = MIN_BW;
			vp->spoofchk = false;
			eth_random_addr(vp->mac);
			dev_info(&adapter->pdev->dev,
				 "MAC Address %pM is configured for VF %d\n",
				 vp->mac, i);
		}
	}

	return 0;

qlcnic_destroy_async_wq:
	while (i--)
		kfree(sriov->vf_info[i].vp);
	destroy_workqueue(bc->bc_async_wq);

qlcnic_destroy_trans_wq:
	destroy_workqueue(bc->bc_trans_wq);

qlcnic_free_vf_info:
	kfree(sriov->vf_info);

qlcnic_free_sriov:
	kfree(adapter->ahw->sriov);
	return err;
}

void qlcnic_sriov_cleanup_list(struct qlcnic_trans_list *t_list)
{
	struct qlcnic_bc_trans *trans;
	struct qlcnic_cmd_args cmd;
	unsigned long flags;

	spin_lock_irqsave(&t_list->lock, flags);

	while (!list_empty(&t_list->wait_list)) {
		trans = list_first_entry(&t_list->wait_list,
					 struct qlcnic_bc_trans, list);
		list_del(&trans->list);
		t_list->count--;
		cmd.req.arg = (u32 *)trans->req_pay;
		cmd.rsp.arg = (u32 *)trans->rsp_pay;
		qlcnic_free_mbx_args(&cmd);
		qlcnic_sriov_cleanup_transaction(trans);
	}

	spin_unlock_irqrestore(&t_list->lock, flags);
}

void __qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_back_channel *bc = &sriov->bc;
	struct qlcnic_vf_info *vf;
	int i;

	if (!qlcnic_sriov_enable_check(adapter))
		return;

	qlcnic_sriov_cleanup_async_list(bc);
	destroy_workqueue(bc->bc_async_wq);

	for (i = 0; i < sriov->num_vfs; i++) {
		vf = &sriov->vf_info[i];
		qlcnic_sriov_cleanup_list(&vf->rcv_pend);
		cancel_work_sync(&vf->trans_work);
		qlcnic_sriov_cleanup_list(&vf->rcv_act);
	}

	destroy_workqueue(bc->bc_trans_wq);

	for (i = 0; i < sriov->num_vfs; i++)
		kfree(sriov->vf_info[i].vp);

	kfree(sriov->vf_info);
	kfree(adapter->ahw->sriov);
}

static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter)
{
	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);
	qlcnic_sriov_cfg_bc_intr(adapter, 0);
	__qlcnic_sriov_cleanup(adapter);
}

void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
{
	if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state))
		return;

	qlcnic_sriov_free_vlans(adapter);

	if (qlcnic_sriov_pf_check(adapter))
		qlcnic_sriov_pf_cleanup(adapter);

	if (qlcnic_sriov_vf_check(adapter))
		qlcnic_sriov_vf_cleanup(adapter);
}

static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
				    u32 *pay, u8 pci_func, u8 size)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_mailbox *mbx = ahw->mailbox;
	struct qlcnic_cmd_args cmd;
	unsigned long timeout;
	int err;

	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
	cmd.hdr = hdr;
	cmd.pay = pay;
	cmd.pay_size = size;
	cmd.func_num = pci_func;
	cmd.op_type = QLC_83XX_MBX_POST_BC_OP;
	cmd.cmd_op = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;

	err = mbx->ops->enqueue_cmd(adapter, &cmd, &timeout);
	if (err) {
		dev_err(&adapter->pdev->dev,
			"%s: Mailbox not available, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
			__func__, cmd.cmd_op, cmd.type, ahw->pci_func,
			ahw->op_mode);
		return err;
	}

	if (!wait_for_completion_timeout(&cmd.completion, timeout)) {
		dev_err(&adapter->pdev->dev,
			"%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
			__func__, cmd.cmd_op, cmd.type, ahw->pci_func,
			ahw->op_mode);
		flush_workqueue(mbx->work_q);
	}

	return cmd.rsp_opcode;
}

static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter)
{
	adapter->num_rxd = QLC_DEFAULT_RCV_DESCRIPTORS_SRIOV_VF;
	adapter->max_rxd = MAX_RCV_DESCRIPTORS_10G;
	adapter->num_jumbo_rxd = QLC_DEFAULT_JUMBO_RCV_DESCRIPTORS_SRIOV_VF;
	adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
	adapter->num_txd = MAX_CMD_DESCRIPTORS;
	adapter->max_rds_rings = MAX_RDS_RINGS;
}

int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *adapter,
				   struct qlcnic_info *npar_info, u16 vport_id)
{
	struct device *dev = &adapter->pdev->dev;
	struct qlcnic_cmd_args cmd;
	int err;
	u32 status;

	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
	if (err)
		return err;

	cmd.req.arg[1] = vport_id << 16 | 0x1;
	err = qlcnic_issue_cmd(adapter, &cmd);
	if (err) {
		dev_err(&adapter->pdev->dev,
			"Failed to get vport info, err=%d\n", err);
		qlcnic_free_mbx_args(&cmd);
		return err;
	}

	status = cmd.rsp.arg[2] & 0xffff;
	if (status & BIT_0)
		npar_info->min_tx_bw = MSW(cmd.rsp.arg[2]);
	if (status & BIT_1)
		npar_info->max_tx_bw = LSW(cmd.rsp.arg[3]);
	if (status & BIT_2)
		npar_info->max_tx_ques = MSW(cmd.rsp.arg[3]);
	if (status & BIT_3)
		npar_info->max_tx_mac_filters = LSW(cmd.rsp.arg[4]);
	if (status & BIT_4)
		npar_info->max_rx_mcast_mac_filters = MSW(cmd.rsp.arg[4]);
	if (status & BIT_5)
		npar_info->max_rx_ucast_mac_filters = LSW(cmd.rsp.arg[5]);
	if (status & BIT_6)
		npar_info->max_rx_ip_addr = MSW(cmd.rsp.arg[5]);
	if (status & BIT_7)
		npar_info->max_rx_lro_flow = LSW(cmd.rsp.arg[6]);
	if (status & BIT_8)
		npar_info->max_rx_status_rings = MSW(cmd.rsp.arg[6]);
	if (status & BIT_9)
		npar_info->max_rx_buf_rings = LSW(cmd.rsp.arg[7]);

	npar_info->max_rx_ques = MSW(cmd.rsp.arg[7]);
	npar_info->max_tx_vlan_keys = LSW(cmd.rsp.arg[8]);
	npar_info->max_local_ipv6_addrs = MSW(cmd.rsp.arg[8]);
	npar_info->max_remote_ipv6_addrs = LSW(cmd.rsp.arg[9]);

	dev_info(dev, "\n\tmin_tx_bw: %d, max_tx_bw: %d max_tx_ques: %d,\n"
		 "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n"
		 "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n"
		 "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n"
		 "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n"
		 "\tlocal_ipv6_addr: %d, remote_ipv6_addr: %d\n",
		 npar_info->min_tx_bw, npar_info->max_tx_bw,
		 npar_info->max_tx_ques, npar_info->max_tx_mac_filters,
		 npar_info->max_rx_mcast_mac_filters,
		 npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr,
		 npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings,
		 npar_info->max_rx_buf_rings, npar_info->max_rx_ques,
		 npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs,
		 npar_info->max_remote_ipv6_addrs);

	qlcnic_free_mbx_args(&cmd);
	return err;
}

static int qlcnic_sriov_set_pvid_mode(struct qlcnic_adapter *adapter,
				      struct qlcnic_cmd_args *cmd)
{
	adapter->rx_pvid = MSW(cmd->rsp.arg[1]) & 0xffff;
	adapter->flags &= ~QLCNIC_TAGGING_ENABLED;
	return 0;
}

static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,
					    struct qlcnic_cmd_args *cmd)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	int i, num_vlans, ret;
	u16 *vlans;

	if (sriov->allowed_vlans)
		return 0;

	sriov->any_vlan = cmd->rsp.arg[2] & 0xf;
	sriov->num_allowed_vlans = cmd->rsp.arg[2] >> 16;
	dev_info(&adapter->pdev->dev, "Number of allowed Guest VLANs = %d\n",
		 sriov->num_allowed_vlans);

	ret = qlcnic_sriov_alloc_vlans(adapter);
	if (ret)
		return ret;

	if (!sriov->any_vlan)
		return 0;

	num_vlans = sriov->num_allowed_vlans;
	sriov->allowed_vlans = kcalloc(num_vlans, sizeof(u16), GFP_KERNEL);
	if (!sriov->allowed_vlans)
		return -ENOMEM;

	vlans = (u16 *)&cmd->rsp.arg[3];
	for (i = 0; i < num_vlans; i++)
		sriov->allowed_vlans[i] = vlans[i];

	return 0;
}

static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_cmd_args cmd;
	int ret = 0;

	memset(&cmd, 0, sizeof(cmd));
	ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd, QLCNIC_BC_CMD_GET_ACL);
	if (ret)
		return ret;

	ret = qlcnic_issue_cmd(adapter, &cmd);
	if (ret) {
		dev_err(&adapter->pdev->dev, "Failed to get ACL, err=%d\n",
			ret);
	} else {
		sriov->vlan_mode = cmd.rsp.arg[1] & 0x3;
		switch (sriov->vlan_mode) {
		case QLC_GUEST_VLAN_MODE:
			ret = qlcnic_sriov_set_guest_vlan_mode(adapter, &cmd);
			break;
		case QLC_PVID_MODE:
			ret = qlcnic_sriov_set_pvid_mode(adapter, &cmd);
			break;
		}
	}

	qlcnic_free_mbx_args(&cmd);
	return ret;
}

static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_info nic_info;
	int err;

	err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0);
	if (err)
		return err;

	ahw->max_mc_count = nic_info.max_rx_mcast_mac_filters;

	err = qlcnic_get_nic_info(adapter, &nic_info, ahw->pci_func);
	if (err)
		return -EIO;

	if (qlcnic_83xx_get_port_info(adapter))
		return -EIO;

	qlcnic_sriov_vf_cfg_buff_desc(adapter);
	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
	dev_info(&adapter->pdev->dev, "HAL Version: %d\n",
		 adapter->ahw->fw_hal_version);

	ahw->physical_port = (u8) nic_info.phys_port;
	ahw->switch_mode = nic_info.switch_mode;
	ahw->max_mtu = nic_info.max_mtu;
	ahw->op_mode = nic_info.op_mode;
	ahw->capabilities = nic_info.capabilities;
	return 0;
}

static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
				 int pci_using_dac)
{
	int err;

	adapter->flags |= QLCNIC_VLAN_FILTERING;
	adapter->ahw->total_nic_func = 1;
	INIT_LIST_HEAD(&adapter->vf_mc_list);
	if (!qlcnic_use_msi_x && !!qlcnic_use_msi)
		dev_warn(&adapter->pdev->dev,
			 "Device does not support MSI interrupts\n");

	/* compute and set default and max tx/sds rings */
	qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING);
	qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING);

	err = qlcnic_setup_intr(adapter);
	if (err) {
		dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
		goto err_out_disable_msi;
	}

	err = qlcnic_83xx_setup_mbx_intr(adapter);
	if (err)
		goto err_out_disable_msi;

	err = qlcnic_sriov_init(adapter, 1);
	if (err)
		goto err_out_disable_mbx_intr;

	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
	if (err)
		goto err_out_cleanup_sriov;

	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);
	if (err)
		goto err_out_disable_bc_intr;

	err = qlcnic_sriov_vf_init_driver(adapter);
	if (err)
		goto err_out_send_channel_term;

	err = qlcnic_sriov_get_vf_acl(adapter);
	if (err)
		goto err_out_send_channel_term;

	err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
	if (err)
		goto err_out_send_channel_term;

	pci_set_drvdata(adapter->pdev, adapter);
	dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
		 adapter->netdev->name);

	qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,
			     adapter->ahw->idc.delay);
	return 0;

err_out_send_channel_term:
	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);

err_out_disable_bc_intr:
	qlcnic_sriov_cfg_bc_intr(adapter, 0);

err_out_cleanup_sriov:
	__qlcnic_sriov_cleanup(adapter);

err_out_disable_mbx_intr:
	qlcnic_83xx_free_mbx_intr(adapter);

err_out_disable_msi:
	qlcnic_teardown_intr(adapter);
	return err;
}

static int qlcnic_sriov_check_dev_ready(struct qlcnic_adapter *adapter)
{
	u32 state;

	do {
		msleep(20);
		if (++adapter->fw_fail_cnt > QLC_BC_CMD_MAX_RETRY_CNT)
			return -EIO;
		state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);
	} while (state != QLC_83XX_IDC_DEV_READY);

	return 0;
}

int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	int err;

	set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status);
	ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
	ahw->reset_context = 0;
	adapter->fw_fail_cnt = 0;
	ahw->msix_supported = 1;
	adapter->need_fw_reset = 0;
	adapter->flags |= QLCNIC_TX_INTR_SHARED;

	err = qlcnic_sriov_check_dev_ready(adapter);
	if (err)
		return err;

	err = qlcnic_sriov_setup_vf(adapter, pci_using_dac);
	if (err)
		return err;

	if (qlcnic_read_mac_addr(adapter))
		dev_warn(&adapter->pdev->dev, "failed to read mac addr\n");

	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);

	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	return 0;
}

void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;

	ahw->op_mode = QLCNIC_SRIOV_VF_FUNC;
	dev_info(&adapter->pdev->dev,
		 "HAL Version: %d Non Privileged SRIOV function\n",
		 ahw->fw_hal_version);
	adapter->nic_ops = &qlcnic_sriov_vf_ops;
	set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
	return;
}

void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *ahw)
{
	ahw->hw_ops		= &qlcnic_sriov_vf_hw_ops;
	ahw->reg_tbl		= (u32 *)qlcnic_83xx_reg_tbl;
	ahw->ext_reg_tbl	= (u32 *)qlcnic_83xx_ext_reg_tbl;
}

static u32 qlcnic_sriov_get_bc_paysize(u32 real_pay_size, u8 curr_frag)
{
	u32 pay_size;

	pay_size = real_pay_size / ((curr_frag + 1) * QLC_BC_PAYLOAD_SZ);

	if (pay_size)
		pay_size = QLC_BC_PAYLOAD_SZ;
	else
		pay_size = real_pay_size % QLC_BC_PAYLOAD_SZ;

	return pay_size;
}

int qlcnic_sriov_func_to_index(struct qlcnic_adapter *adapter, u8 pci_func)
{
	struct qlcnic_vf_info *vf_info = adapter->ahw->sriov->vf_info;
	u8 i;

	if (qlcnic_sriov_vf_check(adapter))
		return 0;

	for (i = 0; i < adapter->ahw->sriov->num_vfs; i++) {
		if (vf_info[i].pci_func == pci_func)
			return i;
	}

	return -EINVAL;
}

static inline int qlcnic_sriov_alloc_bc_trans(struct qlcnic_bc_trans **trans)
{
	*trans = kzalloc(sizeof(struct qlcnic_bc_trans), GFP_ATOMIC);
	if (!*trans)
		return -ENOMEM;

	init_completion(&(*trans)->resp_cmpl);
	return 0;
}

static inline int qlcnic_sriov_alloc_bc_msg(struct qlcnic_bc_hdr **hdr,
					    u32 size)
{
	*hdr = kcalloc(size, sizeof(struct qlcnic_bc_hdr), GFP_ATOMIC);
	if (!*hdr)
		return -ENOMEM;

	return 0;
}

static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *mbx, u32 type)
{
	const struct qlcnic_mailbox_metadata *mbx_tbl;
	int i, size;

	mbx_tbl = qlcnic_sriov_bc_mbx_tbl;
	size = ARRAY_SIZE(qlcnic_sriov_bc_mbx_tbl);

	for (i = 0; i < size; i++) {
		if (type == mbx_tbl[i].cmd) {
			mbx->op_type = QLC_BC_CMD;
			mbx->req.num = mbx_tbl[i].in_args;
			mbx->rsp.num = mbx_tbl[i].out_args;
			mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
					       GFP_ATOMIC);
			if (!mbx->req.arg)
				return -ENOMEM;
			mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
					       GFP_ATOMIC);
			if (!mbx->rsp.arg) {
				kfree(mbx->req.arg);
				mbx->req.arg = NULL;
				return -ENOMEM;
			}
			mbx->req.arg[0] = (type | (mbx->req.num << 16) |
					   (3 << 29));
			mbx->rsp.arg[0] = (type & 0xffff) | mbx->rsp.num << 16;
			return 0;
		}
	}
	return -EINVAL;
}

static int qlcnic_sriov_prepare_bc_hdr(struct qlcnic_bc_trans *trans,
				       struct qlcnic_cmd_args *cmd,
				       u16 seq, u8 msg_type)
{
	struct qlcnic_bc_hdr *hdr;
	int i;
	u32 num_regs, bc_pay_sz;
	u16 remainder;
	u8 cmd_op, num_frags, t_num_frags;

	bc_pay_sz = QLC_BC_PAYLOAD_SZ;
	if (msg_type == QLC_BC_COMMAND) {
		trans->req_pay = (struct qlcnic_bc_payload *)cmd->req.arg;
		trans->rsp_pay = (struct qlcnic_bc_payload *)cmd->rsp.arg;
		num_regs = cmd->req.num;
		trans->req_pay_size = (num_regs * 4);
		num_regs = cmd->rsp.num;
		trans->rsp_pay_size = (num_regs * 4);
		cmd_op = cmd->req.arg[0] & 0xff;
		remainder = (trans->req_pay_size) % (bc_pay_sz);
		num_frags = (trans->req_pay_size) / (bc_pay_sz);
		if (remainder)
			num_frags++;
		t_num_frags = num_frags;
		if (qlcnic_sriov_alloc_bc_msg(&trans->req_hdr, num_frags))
			return -ENOMEM;
		remainder = (trans->rsp_pay_size) % (bc_pay_sz);
		num_frags = (trans->rsp_pay_size) / (bc_pay_sz);
		if (remainder)
			num_frags++;
		if (qlcnic_sriov_alloc_bc_msg(&trans->rsp_hdr, num_frags))
			return -ENOMEM;
		num_frags  = t_num_frags;
		hdr = trans->req_hdr;
	}  else {
		cmd->req.arg = (u32 *)trans->req_pay;
		cmd->rsp.arg = (u32 *)trans->rsp_pay;
		cmd_op = cmd->req.arg[0] & 0xff;
		cmd->cmd_op = cmd_op;
		remainder = (trans->rsp_pay_size) % (bc_pay_sz);
		num_frags = (trans->rsp_pay_size) / (bc_pay_sz);
		if (remainder)
			num_frags++;
		cmd->req.num = trans->req_pay_size / 4;
		cmd->rsp.num = trans->rsp_pay_size / 4;
		hdr = trans->rsp_hdr;
		cmd->op_type = trans->req_hdr->op_type;
	}

	trans->trans_id = seq;
	trans->cmd_id = cmd_op;
	for (i = 0; i < num_frags; i++) {
		hdr[i].version = 2;
		hdr[i].msg_type = msg_type;
		hdr[i].op_type = cmd->op_type;
		hdr[i].num_cmds = 1;
		hdr[i].num_frags = num_frags;
		hdr[i].frag_num = i + 1;
		hdr[i].cmd_op = cmd_op;
		hdr[i].seq_id = seq;
	}
	return 0;
}

static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *trans)
{
	if (!trans)
		return;
	kfree(trans->req_hdr);
	kfree(trans->rsp_hdr);
	kfree(trans);
}

static int qlcnic_sriov_clear_trans(struct qlcnic_vf_info *vf,
				    struct qlcnic_bc_trans *trans, u8 type)
{
	struct qlcnic_trans_list *t_list;
	unsigned long flags;
	int ret = 0;

	if (type == QLC_BC_RESPONSE) {
		t_list = &vf->rcv_act;
		spin_lock_irqsave(&t_list->lock, flags);
		t_list->count--;
		list_del(&trans->list);
		if (t_list->count > 0)
			ret = 1;
		spin_unlock_irqrestore(&t_list->lock, flags);
	}
	if (type == QLC_BC_COMMAND) {
		while (test_and_set_bit(QLC_BC_VF_SEND, &vf->state))
			msleep(100);
		vf->send_cmd = NULL;
		clear_bit(QLC_BC_VF_SEND, &vf->state);
	}
	return ret;
}

static void qlcnic_sriov_schedule_bc_cmd(struct qlcnic_sriov *sriov,
					 struct qlcnic_vf_info *vf,
					 work_func_t func)
{
	if (test_bit(QLC_BC_VF_FLR, &vf->state) ||
	    vf->adapter->need_fw_reset)
		return;

	queue_work(sriov->bc.bc_trans_wq, &vf->trans_work);
}

static inline void qlcnic_sriov_wait_for_resp(struct qlcnic_bc_trans *trans)
{
	struct completion *cmpl = &trans->resp_cmpl;

	if (wait_for_completion_timeout(cmpl, QLC_MBOX_RESP_TIMEOUT))
		trans->trans_state = QLC_END;
	else
		trans->trans_state = QLC_ABORT;

	return;
}

static void qlcnic_sriov_handle_multi_frags(struct qlcnic_bc_trans *trans,
					    u8 type)
{
	if (type == QLC_BC_RESPONSE) {
		trans->curr_rsp_frag++;
		if (trans->curr_rsp_frag < trans->rsp_hdr->num_frags)
			trans->trans_state = QLC_INIT;
		else
			trans->trans_state = QLC_END;
	} else {
		trans->curr_req_frag++;
		if (trans->curr_req_frag < trans->req_hdr->num_frags)
			trans->trans_state = QLC_INIT;
		else
			trans->trans_state = QLC_WAIT_FOR_RESP;
	}
}

static void qlcnic_sriov_wait_for_channel_free(struct qlcnic_bc_trans *trans,
					       u8 type)
{
	struct qlcnic_vf_info *vf = trans->vf;
	struct completion *cmpl = &vf->ch_free_cmpl;

	if (!wait_for_completion_timeout(cmpl, QLC_MBOX_CH_FREE_TIMEOUT)) {
		trans->trans_state = QLC_ABORT;
		return;
	}

	clear_bit(QLC_BC_VF_CHANNEL, &vf->state);
	qlcnic_sriov_handle_multi_frags(trans, type);
}

static void qlcnic_sriov_pull_bc_msg(struct qlcnic_adapter *adapter,
				     u32 *hdr, u32 *pay, u32 size)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	u8 i, max = 2, hdr_size, j;

	hdr_size = (sizeof(struct qlcnic_bc_hdr) / sizeof(u32));
	max = (size / sizeof(u32)) + hdr_size;

	for (i = 2, j = 0; j < hdr_size; i++, j++)
		*(hdr++) = readl(QLCNIC_MBX_FW(ahw, i));
	for (; j < max; i++, j++)
		*(pay++) = readl(QLCNIC_MBX_FW(ahw, i));
}

static int __qlcnic_sriov_issue_bc_post(struct qlcnic_vf_info *vf)
{
	int ret = -EBUSY;
	u32 timeout = 10000;

	do {
		if (!test_and_set_bit(QLC_BC_VF_CHANNEL, &vf->state)) {
			ret = 0;
			break;
		}
		mdelay(1);
	} while (--timeout);

	return ret;
}

static int qlcnic_sriov_issue_bc_post(struct qlcnic_bc_trans *trans, u8 type)
{
	struct qlcnic_vf_info *vf = trans->vf;
	u32 pay_size;
	u32 *hdr, *pay;
	int ret;
	u8 pci_func = trans->func_id;

	if (__qlcnic_sriov_issue_bc_post(vf))
		return -EBUSY;

	if (type == QLC_BC_COMMAND) {
		hdr = (u32 *)(trans->req_hdr + trans->curr_req_frag);
		pay = (u32 *)(trans->req_pay + trans->curr_req_frag);
		pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,
						       trans->curr_req_frag);
		pay_size = (pay_size / sizeof(u32));
	} else {
		hdr = (u32 *)(trans->rsp_hdr + trans->curr_rsp_frag);
		pay = (u32 *)(trans->rsp_pay + trans->curr_rsp_frag);
		pay_size = qlcnic_sriov_get_bc_paysize(trans->rsp_pay_size,
						       trans->curr_rsp_frag);
		pay_size = (pay_size / sizeof(u32));
	}

	ret = qlcnic_sriov_post_bc_msg(vf->adapter, hdr, pay,
				       pci_func, pay_size);
	return ret;
}

static int __qlcnic_sriov_send_bc_msg(struct qlcnic_bc_trans *trans,
				      struct qlcnic_vf_info *vf, u8 type)
{
	bool flag = true;
	int err = -EIO;

	while (flag) {
		if (test_bit(QLC_BC_VF_FLR, &vf->state) ||
		    vf->adapter->need_fw_reset)
			trans->trans_state = QLC_ABORT;

		switch (trans->trans_state) {
		case QLC_INIT:
			trans->trans_state = QLC_WAIT_FOR_CHANNEL_FREE;
			if (qlcnic_sriov_issue_bc_post(trans, type))
				trans->trans_state = QLC_ABORT;
			break;
		case QLC_WAIT_FOR_CHANNEL_FREE:
			qlcnic_sriov_wait_for_channel_free(trans, type);
			break;
		case QLC_WAIT_FOR_RESP:
			qlcnic_sriov_wait_for_resp(trans);
			break;
		case QLC_END:
			err = 0;
			flag = false;
			break;
		case QLC_ABORT:
			err = -EIO;
			flag = false;
			clear_bit(QLC_BC_VF_CHANNEL, &vf->state);
			break;
		default:
			err = -EIO;
			flag = false;
		}
	}
	return err;
}

static int qlcnic_sriov_send_bc_cmd(struct qlcnic_adapter *adapter,
				    struct qlcnic_bc_trans *trans, int pci_func)
{
	struct qlcnic_vf_info *vf;
	int err, index = qlcnic_sriov_func_to_index(adapter, pci_func);

	if (index < 0)
		return -EIO;

	vf = &adapter->ahw->sriov->vf_info[index];
	trans->vf = vf;
	trans->func_id = pci_func;

	if (!test_bit(QLC_BC_VF_STATE, &vf->state)) {
		if (qlcnic_sriov_pf_check(adapter))
			return -EIO;
		if (qlcnic_sriov_vf_check(adapter) &&
		    trans->cmd_id != QLCNIC_BC_CMD_CHANNEL_INIT)
			return -EIO;
	}

	mutex_lock(&vf->send_cmd_lock);
	vf->send_cmd = trans;
	err = __qlcnic_sriov_send_bc_msg(trans, vf, QLC_BC_COMMAND);
	qlcnic_sriov_clear_trans(vf, trans, QLC_BC_COMMAND);
	mutex_unlock(&vf->send_cmd_lock);
	return err;
}

static void __qlcnic_sriov_process_bc_cmd(struct qlcnic_adapter *adapter,
					  struct qlcnic_bc_trans *trans,
					  struct qlcnic_cmd_args *cmd)
{
#ifdef CONFIG_QLCNIC_SRIOV
	if (qlcnic_sriov_pf_check(adapter)) {
		qlcnic_sriov_pf_process_bc_cmd(adapter, trans, cmd);
		return;
	}
#endif
	cmd->rsp.arg[0] |= (0x9 << 25);
	return;
}

static void qlcnic_sriov_process_bc_cmd(struct work_struct *work)
{
	struct qlcnic_vf_info *vf = container_of(work, struct qlcnic_vf_info,
						 trans_work);
	struct qlcnic_bc_trans *trans = NULL;
	struct qlcnic_adapter *adapter  = vf->adapter;
	struct qlcnic_cmd_args cmd;
	u8 req;

	if (adapter->need_fw_reset)
		return;

	if (test_bit(QLC_BC_VF_FLR, &vf->state))
		return;

	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
	trans = list_first_entry(&vf->rcv_act.wait_list,
				 struct qlcnic_bc_trans, list);
	adapter = vf->adapter;

	if (qlcnic_sriov_prepare_bc_hdr(trans, &cmd, trans->req_hdr->seq_id,
					QLC_BC_RESPONSE))
		goto cleanup_trans;

	__qlcnic_sriov_process_bc_cmd(adapter, trans, &cmd);
	trans->trans_state = QLC_INIT;
	__qlcnic_sriov_send_bc_msg(trans, vf, QLC_BC_RESPONSE);

cleanup_trans:
	qlcnic_free_mbx_args(&cmd);
	req = qlcnic_sriov_clear_trans(vf, trans, QLC_BC_RESPONSE);
	qlcnic_sriov_cleanup_transaction(trans);
	if (req)
		qlcnic_sriov_schedule_bc_cmd(adapter->ahw->sriov, vf,
					     qlcnic_sriov_process_bc_cmd);
}

static void qlcnic_sriov_handle_bc_resp(struct qlcnic_bc_hdr *hdr,
					struct qlcnic_vf_info *vf)
{
	struct qlcnic_bc_trans *trans;
	u32 pay_size;

	if (test_and_set_bit(QLC_BC_VF_SEND, &vf->state))
		return;

	trans = vf->send_cmd;

	if (trans == NULL)
		goto clear_send;

	if (trans->trans_id != hdr->seq_id)
		goto clear_send;

	pay_size = qlcnic_sriov_get_bc_paysize(trans->rsp_pay_size,
					       trans->curr_rsp_frag);
	qlcnic_sriov_pull_bc_msg(vf->adapter,
				 (u32 *)(trans->rsp_hdr + trans->curr_rsp_frag),
				 (u32 *)(trans->rsp_pay + trans->curr_rsp_frag),
				 pay_size);
	if (++trans->curr_rsp_frag < trans->rsp_hdr->num_frags)
		goto clear_send;

	complete(&trans->resp_cmpl);

clear_send:
	clear_bit(QLC_BC_VF_SEND, &vf->state);
}

int __qlcnic_sriov_add_act_list(struct qlcnic_sriov *sriov,
				struct qlcnic_vf_info *vf,
				struct qlcnic_bc_trans *trans)
{
	struct qlcnic_trans_list *t_list = &vf->rcv_act;

	t_list->count++;
	list_add_tail(&trans->list, &t_list->wait_list);
	if (t_list->count == 1)
		qlcnic_sriov_schedule_bc_cmd(sriov, vf,
					     qlcnic_sriov_process_bc_cmd);
	return 0;
}

static int qlcnic_sriov_add_act_list(struct qlcnic_sriov *sriov,
				     struct qlcnic_vf_info *vf,
				     struct qlcnic_bc_trans *trans)
{
	struct qlcnic_trans_list *t_list = &vf->rcv_act;

	spin_lock(&t_list->lock);

	__qlcnic_sriov_add_act_list(sriov, vf, trans);

	spin_unlock(&t_list->lock);
	return 0;
}

static void qlcnic_sriov_handle_pending_trans(struct qlcnic_sriov *sriov,
					      struct qlcnic_vf_info *vf,
					      struct qlcnic_bc_hdr *hdr)
{
	struct qlcnic_bc_trans *trans = NULL;
	struct list_head *node;
	u32 pay_size, curr_frag;
	u8 found = 0, active = 0;

	spin_lock(&vf->rcv_pend.lock);
	if (vf->rcv_pend.count > 0) {
		list_for_each(node, &vf->rcv_pend.wait_list) {
			trans = list_entry(node, struct qlcnic_bc_trans, list);
			if (trans->trans_id == hdr->seq_id) {
				found = 1;
				break;
			}
		}
	}

	if (found) {
		curr_frag = trans->curr_req_frag;
		pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,
						       curr_frag);
		qlcnic_sriov_pull_bc_msg(vf->adapter,
					 (u32 *)(trans->req_hdr + curr_frag),
					 (u32 *)(trans->req_pay + curr_frag),
					 pay_size);
		trans->curr_req_frag++;
		if (trans->curr_req_frag >= hdr->num_frags) {
			vf->rcv_pend.count--;
			list_del(&trans->list);
			active = 1;
		}
	}
	spin_unlock(&vf->rcv_pend.lock);

	if (active)
		if (qlcnic_sriov_add_act_list(sriov, vf, trans))
			qlcnic_sriov_cleanup_transaction(trans);

	return;
}

static void qlcnic_sriov_handle_bc_cmd(struct qlcnic_sriov *sriov,
				       struct qlcnic_bc_hdr *hdr,
				       struct qlcnic_vf_info *vf)
{
	struct qlcnic_bc_trans *trans;
	struct qlcnic_adapter *adapter = vf->adapter;
	struct qlcnic_cmd_args cmd;
	u32 pay_size;
	int err;
	u8 cmd_op;

	if (adapter->need_fw_reset)
		return;

	if (!test_bit(QLC_BC_VF_STATE, &vf->state) &&
	    hdr->op_type != QLC_BC_CMD &&
	    hdr->cmd_op != QLCNIC_BC_CMD_CHANNEL_INIT)
		return;

	if (hdr->frag_num > 1) {
		qlcnic_sriov_handle_pending_trans(sriov, vf, hdr);
		return;
	}

	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
	cmd_op = hdr->cmd_op;
	if (qlcnic_sriov_alloc_bc_trans(&trans))
		return;

	if (hdr->op_type == QLC_BC_CMD)
		err = qlcnic_sriov_alloc_bc_mbx_args(&cmd, cmd_op);
	else
		err = qlcnic_alloc_mbx_args(&cmd, adapter, cmd_op);

	if (err) {
		qlcnic_sriov_cleanup_transaction(trans);
		return;
	}

	cmd.op_type = hdr->op_type;
	if (qlcnic_sriov_prepare_bc_hdr(trans, &cmd, hdr->seq_id,
					QLC_BC_COMMAND)) {
		qlcnic_free_mbx_args(&cmd);
		qlcnic_sriov_cleanup_transaction(trans);
		return;
	}

	pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,
					 trans->curr_req_frag);
	qlcnic_sriov_pull_bc_msg(vf->adapter,
				 (u32 *)(trans->req_hdr + trans->curr_req_frag),
				 (u32 *)(trans->req_pay + trans->curr_req_frag),
				 pay_size);
	trans->func_id = vf->pci_func;
	trans->vf = vf;
	trans->trans_id = hdr->seq_id;
	trans->curr_req_frag++;

	if (qlcnic_sriov_soft_flr_check(adapter, trans, vf))
		return;

	if (trans->curr_req_frag == trans->req_hdr->num_frags) {
		if (qlcnic_sriov_add_act_list(sriov, vf, trans)) {
			qlcnic_free_mbx_args(&cmd);
			qlcnic_sriov_cleanup_transaction(trans);
		}
	} else {
		spin_lock(&vf->rcv_pend.lock);
		list_add_tail(&trans->list, &vf->rcv_pend.wait_list);
		vf->rcv_pend.count++;
		spin_unlock(&vf->rcv_pend.lock);
	}
}

static void qlcnic_sriov_handle_msg_event(struct qlcnic_sriov *sriov,
					  struct qlcnic_vf_info *vf)
{
	struct qlcnic_bc_hdr hdr;
	u32 *ptr = (u32 *)&hdr;
	u8 msg_type, i;

	for (i = 2; i < 6; i++)
		ptr[i - 2] = readl(QLCNIC_MBX_FW(vf->adapter->ahw, i));
	msg_type = hdr.msg_type;

	switch (msg_type) {
	case QLC_BC_COMMAND:
		qlcnic_sriov_handle_bc_cmd(sriov, &hdr, vf);
		break;
	case QLC_BC_RESPONSE:
		qlcnic_sriov_handle_bc_resp(&hdr, vf);
		break;
	}
}

static void qlcnic_sriov_handle_flr_event(struct qlcnic_sriov *sriov,
					  struct qlcnic_vf_info *vf)
{
	struct qlcnic_adapter *adapter = vf->adapter;

	if (qlcnic_sriov_pf_check(adapter))
		qlcnic_sriov_pf_handle_flr(sriov, vf);
	else
		dev_err(&adapter->pdev->dev,
			"Invalid event to VF. VF should not get FLR event\n");
}

void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *adapter, u32 event)
{
	struct qlcnic_vf_info *vf;
	struct qlcnic_sriov *sriov;
	int index;
	u8 pci_func;

	sriov = adapter->ahw->sriov;
	pci_func = qlcnic_sriov_target_func_id(event);
	index = qlcnic_sriov_func_to_index(adapter, pci_func);

	if (index < 0)
		return;

	vf = &sriov->vf_info[index];
	vf->pci_func = pci_func;

	if (qlcnic_sriov_channel_free_check(event))
		complete(&vf->ch_free_cmpl);

	if (qlcnic_sriov_flr_check(event)) {
		qlcnic_sriov_handle_flr_event(sriov, vf);
		return;
	}

	if (qlcnic_sriov_bc_msg_check(event))
		qlcnic_sriov_handle_msg_event(sriov, vf);
}

int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *adapter, u8 enable)
{
	struct qlcnic_cmd_args cmd;
	int err;

	if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state))
		return 0;

	if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_BC_EVENT_SETUP))
		return -ENOMEM;

	if (enable)
		cmd.req.arg[1] = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7);

	err = qlcnic_83xx_issue_cmd(adapter, &cmd);

	if (err != QLCNIC_RCODE_SUCCESS) {
		dev_err(&adapter->pdev->dev,
			"Failed to %s bc events, err=%d\n",
			(enable ? "enable" : "disable"), err);
	}

	qlcnic_free_mbx_args(&cmd);
	return err;
}

static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter,
				     struct qlcnic_bc_trans *trans)
{
	u8 max = QLC_BC_CMD_MAX_RETRY_CNT;
	u32 state;

	state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);
	if (state == QLC_83XX_IDC_DEV_READY) {
		msleep(20);
		clear_bit(QLC_BC_VF_CHANNEL, &trans->vf->state);
		trans->trans_state = QLC_INIT;
		if (++adapter->fw_fail_cnt > max)
			return -EIO;
		else
			return 0;
	}

	return -EIO;
}

static int __qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
				  struct qlcnic_cmd_args *cmd)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_mailbox *mbx = ahw->mailbox;
	struct device *dev = &adapter->pdev->dev;
	struct qlcnic_bc_trans *trans;
	int err;
	u32 rsp_data, opcode, mbx_err_code, rsp;
	u16 seq = ++adapter->ahw->sriov->bc.trans_counter;
	u8 func = ahw->pci_func;

	rsp = qlcnic_sriov_alloc_bc_trans(&trans);
	if (rsp)
		goto free_cmd;

	rsp = qlcnic_sriov_prepare_bc_hdr(trans, cmd, seq, QLC_BC_COMMAND);
	if (rsp)
		goto cleanup_transaction;

retry:
	if (!test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
		rsp = -EIO;
		QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n",
		      QLCNIC_MBX_RSP(cmd->req.arg[0]), func);
		goto err_out;
	}

	err = qlcnic_sriov_send_bc_cmd(adapter, trans, func);
	if (err) {
		dev_err(dev, "MBX command 0x%x timed out for VF %d\n",
			(cmd->req.arg[0] & 0xffff), func);
		rsp = QLCNIC_RCODE_TIMEOUT;

		/* After adapter reset PF driver may take some time to
		 * respond to VF's request. Retry request till maximum retries.
		 */
		if ((trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) &&
		    !qlcnic_sriov_retry_bc_cmd(adapter, trans))
			goto retry;

		goto err_out;
	}

	rsp_data = cmd->rsp.arg[0];
	mbx_err_code = QLCNIC_MBX_STATUS(rsp_data);
	opcode = QLCNIC_MBX_RSP(cmd->req.arg[0]);

	if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||
	    (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {
		rsp = QLCNIC_RCODE_SUCCESS;
	} else {
		if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
			rsp = QLCNIC_RCODE_SUCCESS;
		} else {
			rsp = mbx_err_code;
			if (!rsp)
				rsp = 1;

			dev_err(dev,
				"MBX command 0x%x failed with err:0x%x for VF %d\n",
				opcode, mbx_err_code, func);
		}
	}

err_out:
	if (rsp == QLCNIC_RCODE_TIMEOUT) {
		ahw->reset_context = 1;
		adapter->need_fw_reset = 1;
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
	}

cleanup_transaction:
	qlcnic_sriov_cleanup_transaction(trans);

free_cmd:
	if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
		qlcnic_free_mbx_args(cmd);
		kfree(cmd);
	}

	return rsp;
}


static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
				  struct qlcnic_cmd_args *cmd)
{
	if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT)
		return qlcnic_sriov_async_issue_cmd(adapter, cmd);
	else
		return __qlcnic_sriov_issue_cmd(adapter, cmd);
}

static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op)
{
	struct qlcnic_cmd_args cmd;
	struct qlcnic_vf_info *vf = &adapter->ahw->sriov->vf_info[0];
	int ret;

	memset(&cmd, 0, sizeof(cmd));
	if (qlcnic_sriov_alloc_bc_mbx_args(&cmd, cmd_op))
		return -ENOMEM;

	ret = qlcnic_issue_cmd(adapter, &cmd);
	if (ret) {
		dev_err(&adapter->pdev->dev,
			"Failed bc channel %s %d\n", cmd_op ? "term" : "init",
			ret);
		goto out;
	}

	cmd_op = (cmd.rsp.arg[0] & 0xff);
	if (cmd.rsp.arg[0] >> 25 == 2)
		return 2;
	if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
		set_bit(QLC_BC_VF_STATE, &vf->state);
	else
		clear_bit(QLC_BC_VF_STATE, &vf->state);

out:
	qlcnic_free_mbx_args(&cmd);
	return ret;
}

static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac,
				  enum qlcnic_mac_type mac_type)
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_vf_info *vf;
	u16 vlan_id;
	int i;

	vf = &adapter->ahw->sriov->vf_info[0];

	if (!qlcnic_sriov_check_any_vlan(vf)) {
		qlcnic_nic_add_mac(adapter, mac, 0, mac_type);
	} else {
		spin_lock(&vf->vlan_list_lock);
		for (i = 0; i < sriov->num_allowed_vlans; i++) {
			vlan_id = vf->sriov_vlans[i];
			if (vlan_id)
				qlcnic_nic_add_mac(adapter, mac, vlan_id,
						   mac_type);
		}
		spin_unlock(&vf->vlan_list_lock);
		if (qlcnic_84xx_check(adapter))
			qlcnic_nic_add_mac(adapter, mac, 0, mac_type);
	}
}

void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc)
{
	struct list_head *head = &bc->async_cmd_list;
	struct qlcnic_async_cmd *entry;

	flush_workqueue(bc->bc_async_wq);
	cancel_work_sync(&bc->vf_async_work);

	spin_lock(&bc->queue_lock);
	while (!list_empty(head)) {
		entry = list_entry(head->next, struct qlcnic_async_cmd,
				   list);
		list_del(&entry->list);
		kfree(entry->cmd);
		kfree(entry);
	}
	spin_unlock(&bc->queue_lock);
}

void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	static const u8 bcast_addr[ETH_ALEN] = {
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
	};
	struct netdev_hw_addr *ha;
	u32 mode = VPORT_MISS_MODE_DROP;

	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return;

	if (netdev->flags & IFF_PROMISC) {
		if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
			mode = VPORT_MISS_MODE_ACCEPT_ALL;
	} else if ((netdev->flags & IFF_ALLMULTI) ||
		   (netdev_mc_count(netdev) > ahw->max_mc_count)) {
		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
	} else {
		qlcnic_vf_add_mc_list(netdev, bcast_addr, QLCNIC_BROADCAST_MAC);
		if (!netdev_mc_empty(netdev)) {
			qlcnic_flush_mcast_mac(adapter);
			netdev_for_each_mc_addr(ha, netdev)
				qlcnic_vf_add_mc_list(netdev, ha->addr,
						      QLCNIC_MULTICAST_MAC);
		}
	}

	/* configure unicast MAC address, if there is not sufficient space
	 * to store all the unicast addresses then enable promiscuous mode
	 */
	if (netdev_uc_count(netdev) > ahw->max_uc_count) {
		mode = VPORT_MISS_MODE_ACCEPT_ALL;
	} else if (!netdev_uc_empty(netdev)) {
		netdev_for_each_uc_addr(ha, netdev)
			qlcnic_vf_add_mc_list(netdev, ha->addr,
					      QLCNIC_UNICAST_MAC);
	}

	if (adapter->pdev->is_virtfn) {
		if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&
		    !adapter->fdb_mac_learn) {
			qlcnic_alloc_lb_filters_mem(adapter);
			adapter->drv_mac_learn = 1;
			adapter->rx_mac_learn = true;
		} else {
			adapter->drv_mac_learn = 0;
			adapter->rx_mac_learn = false;
		}
	}

	qlcnic_nic_set_promisc(adapter, mode);
}

static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work)
{
	struct qlcnic_async_cmd *entry, *tmp;
	struct qlcnic_back_channel *bc;
	struct qlcnic_cmd_args *cmd;
	struct list_head *head;
	LIST_HEAD(del_list);

	bc = container_of(work, struct qlcnic_back_channel, vf_async_work);
	head = &bc->async_cmd_list;

	spin_lock(&bc->queue_lock);
	list_splice_init(head, &del_list);
	spin_unlock(&bc->queue_lock);

	list_for_each_entry_safe(entry, tmp, &del_list, list) {
		list_del(&entry->list);
		cmd = entry->cmd;
		__qlcnic_sriov_issue_cmd(bc->adapter, cmd);
		kfree(entry);
	}

	if (!list_empty(head))
		queue_work(bc->bc_async_wq, &bc->vf_async_work);

	return;
}

static struct qlcnic_async_cmd *
qlcnic_sriov_alloc_async_cmd(struct qlcnic_back_channel *bc,
			     struct qlcnic_cmd_args *cmd)
{
	struct qlcnic_async_cmd *entry = NULL;

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return NULL;

	entry->cmd = cmd;

	spin_lock(&bc->queue_lock);
	list_add_tail(&entry->list, &bc->async_cmd_list);
	spin_unlock(&bc->queue_lock);

	return entry;
}

static void qlcnic_sriov_schedule_async_cmd(struct qlcnic_back_channel *bc,
					    struct qlcnic_cmd_args *cmd)
{
	struct qlcnic_async_cmd *entry = NULL;

	entry = qlcnic_sriov_alloc_async_cmd(bc, cmd);
	if (!entry) {
		qlcnic_free_mbx_args(cmd);
		kfree(cmd);
		return;
	}

	queue_work(bc->bc_async_wq, &bc->vf_async_work);
}

static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *adapter,
					struct qlcnic_cmd_args *cmd)
{

	struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc;

	if (adapter->need_fw_reset)
		return -EIO;

	qlcnic_sriov_schedule_async_cmd(bc, cmd);

	return 0;
}

static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
{
	int err;

	adapter->need_fw_reset = 0;
	qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox);
	qlcnic_83xx_enable_mbx_interrupt(adapter);

	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
	if (err)
		return err;

	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);
	if (err)
		goto err_out_cleanup_bc_intr;

	err = qlcnic_sriov_vf_init_driver(adapter);
	if (err)
		goto err_out_term_channel;

	return 0;

err_out_term_channel:
	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);

err_out_cleanup_bc_intr:
	qlcnic_sriov_cfg_bc_intr(adapter, 0);
	return err;
}

static void qlcnic_sriov_vf_attach(struct qlcnic_adapter *adapter)
{
	struct net_device *netdev = adapter->netdev;

	if (netif_running(netdev)) {
		if (!qlcnic_up(adapter, netdev))
			qlcnic_restore_indev_addr(netdev, NETDEV_UP);
	}

	netif_device_attach(netdev);
}

static void qlcnic_sriov_vf_detach(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_intrpt_config *intr_tbl = ahw->intr_tbl;
	struct net_device *netdev = adapter->netdev;
	u8 i, max_ints = ahw->num_msix - 1;

	netif_device_detach(netdev);
	qlcnic_83xx_detach_mailbox_work(adapter);
	qlcnic_83xx_disable_mbx_intr(adapter);

	if (netif_running(netdev))
		qlcnic_down(adapter, netdev);

	for (i = 0; i < max_ints; i++) {
		intr_tbl[i].id = i;
		intr_tbl[i].enabled = 0;
		intr_tbl[i].src = 0;
	}
	ahw->reset_context = 0;
}

static int qlcnic_sriov_vf_handle_dev_ready(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct device *dev = &adapter->pdev->dev;
	struct qlc_83xx_idc *idc = &ahw->idc;
	u8 func = ahw->pci_func;
	u32 state;

	if ((idc->prev_state == QLC_83XX_IDC_DEV_NEED_RESET) ||
	    (idc->prev_state == QLC_83XX_IDC_DEV_INIT)) {
		if (!qlcnic_sriov_vf_reinit_driver(adapter)) {
			qlcnic_sriov_vf_attach(adapter);
			adapter->fw_fail_cnt = 0;
			dev_info(dev,
				 "%s: Reinitialization of VF 0x%x done after FW reset\n",
				 __func__, func);
		} else {
			dev_err(dev,
				"%s: Reinitialization of VF 0x%x failed after FW reset\n",
				__func__, func);
			state = QLCRDX(ahw, QLC_83XX_IDC_DEV_STATE);
			dev_info(dev, "Current state 0x%x after FW reset\n",
				 state);
		}
	}

	return 0;
}

static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_mailbox *mbx = ahw->mailbox;
	struct device *dev = &adapter->pdev->dev;
	struct qlc_83xx_idc *idc = &ahw->idc;
	u8 func = ahw->pci_func;
	u32 state;

	adapter->reset_ctx_cnt++;

	/* Skip the context reset and check if FW is hung */
	if (adapter->reset_ctx_cnt < 3) {
		adapter->need_fw_reset = 1;
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
		dev_info(dev,
			 "Resetting context, wait here to check if FW is in failed state\n");
		return 0;
	}

	/* Check if number of resets exceed the threshold.
	 * If it exceeds the threshold just fail the VF.
	 */
	if (adapter->reset_ctx_cnt > QLC_83XX_VF_RESET_FAIL_THRESH) {
		clear_bit(QLC_83XX_MODULE_LOADED, &idc->status);
		adapter->tx_timeo_cnt = 0;
		adapter->fw_fail_cnt = 0;
		adapter->reset_ctx_cnt = 0;
		qlcnic_sriov_vf_detach(adapter);
		dev_err(dev,
			"Device context resets have exceeded the threshold, device interface will be shutdown\n");
		return -EIO;
	}

	dev_info(dev, "Resetting context of VF 0x%x\n", func);
	dev_info(dev, "%s: Context reset count %d for VF 0x%x\n",
		 __func__, adapter->reset_ctx_cnt, func);
	set_bit(__QLCNIC_RESETTING, &adapter->state);
	adapter->need_fw_reset = 1;
	clear_bit(QLC_83XX_MBX_READY, &mbx->status);
	qlcnic_sriov_vf_detach(adapter);
	adapter->need_fw_reset = 0;

	if (!qlcnic_sriov_vf_reinit_driver(adapter)) {
		qlcnic_sriov_vf_attach(adapter);
		adapter->tx_timeo_cnt = 0;
		adapter->reset_ctx_cnt = 0;
		adapter->fw_fail_cnt = 0;
		dev_info(dev, "Done resetting context for VF 0x%x\n", func);
	} else {
		dev_err(dev, "%s: Reinitialization of VF 0x%x failed\n",
			__func__, func);
		state = QLCRDX(ahw, QLC_83XX_IDC_DEV_STATE);
		dev_info(dev, "%s: Current state 0x%x\n", __func__, state);
	}

	return 0;
}

static int qlcnic_sriov_vf_idc_ready_state(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	int ret = 0;

	if (ahw->idc.prev_state != QLC_83XX_IDC_DEV_READY)
		ret = qlcnic_sriov_vf_handle_dev_ready(adapter);
	else if (ahw->reset_context)
		ret = qlcnic_sriov_vf_handle_context_reset(adapter);

	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	return ret;
}

static int qlcnic_sriov_vf_idc_failed_state(struct qlcnic_adapter *adapter)
{
	struct qlc_83xx_idc *idc = &adapter->ahw->idc;

	dev_err(&adapter->pdev->dev, "Device is in failed state\n");
	if (idc->prev_state == QLC_83XX_IDC_DEV_READY)
		qlcnic_sriov_vf_detach(adapter);

	clear_bit(QLC_83XX_MODULE_LOADED, &idc->status);
	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	return -EIO;
}

static int
qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
{
	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
	struct qlc_83xx_idc *idc = &adapter->ahw->idc;

	dev_info(&adapter->pdev->dev, "Device is in quiescent state\n");
	if (idc->prev_state == QLC_83XX_IDC_DEV_READY) {
		set_bit(__QLCNIC_RESETTING, &adapter->state);
		adapter->tx_timeo_cnt = 0;
		adapter->reset_ctx_cnt = 0;
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
		qlcnic_sriov_vf_detach(adapter);
	}

	return 0;
}

static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)
{
	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
	struct qlc_83xx_idc *idc = &adapter->ahw->idc;
	u8 func = adapter->ahw->pci_func;

	if (idc->prev_state == QLC_83XX_IDC_DEV_READY) {
		dev_err(&adapter->pdev->dev,
			"Firmware hang detected by VF 0x%x\n", func);
		set_bit(__QLCNIC_RESETTING, &adapter->state);
		adapter->tx_timeo_cnt = 0;
		adapter->reset_ctx_cnt = 0;
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
		qlcnic_sriov_vf_detach(adapter);
	}
	return 0;
}

static int qlcnic_sriov_vf_idc_unknown_state(struct qlcnic_adapter *adapter)
{
	dev_err(&adapter->pdev->dev, "%s: Device in unknown state\n", __func__);
	return 0;
}

static void qlcnic_sriov_vf_periodic_tasks(struct qlcnic_adapter *adapter)
{
	if (adapter->fhash.fnum)
		qlcnic_prune_lb_filters(adapter);
}

static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work)
{
	struct qlcnic_adapter *adapter;
	struct qlc_83xx_idc *idc;
	int ret = 0;

	adapter = container_of(work, struct qlcnic_adapter, fw_work.work);
	idc = &adapter->ahw->idc;
	idc->curr_state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);

	switch (idc->curr_state) {
	case QLC_83XX_IDC_DEV_READY:
		ret = qlcnic_sriov_vf_idc_ready_state(adapter);
		break;
	case QLC_83XX_IDC_DEV_NEED_RESET:
	case QLC_83XX_IDC_DEV_INIT:
		ret = qlcnic_sriov_vf_idc_init_reset_state(adapter);
		break;
	case QLC_83XX_IDC_DEV_NEED_QUISCENT:
		ret = qlcnic_sriov_vf_idc_need_quiescent_state(adapter);
		break;
	case QLC_83XX_IDC_DEV_FAILED:
		ret = qlcnic_sriov_vf_idc_failed_state(adapter);
		break;
	case QLC_83XX_IDC_DEV_QUISCENT:
		break;
	default:
		ret = qlcnic_sriov_vf_idc_unknown_state(adapter);
	}

	idc->prev_state = idc->curr_state;
	qlcnic_sriov_vf_periodic_tasks(adapter);

	if (!ret && test_bit(QLC_83XX_MODULE_LOADED, &idc->status))
		qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,
				     idc->delay);
}

static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *adapter)
{
	while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
		msleep(20);

	clear_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
	clear_bit(__QLCNIC_RESETTING, &adapter->state);
	cancel_delayed_work_sync(&adapter->fw_work);
}

static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov,
				      struct qlcnic_vf_info *vf, u16 vlan_id)
{
	int i, err = -EINVAL;

	if (!vf->sriov_vlans)
		return err;

	spin_lock_bh(&vf->vlan_list_lock);

	for (i = 0; i < sriov->num_allowed_vlans; i++) {
		if (vf->sriov_vlans[i] == vlan_id) {
			err = 0;
			break;
		}
	}

	spin_unlock_bh(&vf->vlan_list_lock);
	return err;
}

static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov,
					   struct qlcnic_vf_info *vf)
{
	int err = 0;

	spin_lock_bh(&vf->vlan_list_lock);

	if (vf->num_vlan >= sriov->num_allowed_vlans)
		err = -EINVAL;

	spin_unlock_bh(&vf->vlan_list_lock);
	return err;
}

static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_adapter *adapter,
					  u16 vid, u8 enable)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_vf_info *vf;
	bool vlan_exist;
	u8 allowed = 0;
	int i;

	vf = &adapter->ahw->sriov->vf_info[0];
	vlan_exist = qlcnic_sriov_check_any_vlan(vf);
	if (sriov->vlan_mode != QLC_GUEST_VLAN_MODE)
		return -EINVAL;

	if (enable) {
		if (qlcnic_83xx_vf_check(adapter) && vlan_exist)
			return -EINVAL;

		if (qlcnic_sriov_validate_num_vlans(sriov, vf))
			return -EINVAL;

		if (sriov->any_vlan) {
			for (i = 0; i < sriov->num_allowed_vlans; i++) {
				if (sriov->allowed_vlans[i] == vid)
					allowed = 1;
			}

			if (!allowed)
				return -EINVAL;
		}
	} else {
		if (!vlan_exist || qlcnic_sriov_check_vlan_id(sriov, vf, vid))
			return -EINVAL;
	}

	return 0;
}

static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id,
					enum qlcnic_vlan_operations opcode)
{
	struct qlcnic_adapter *adapter = vf->adapter;
	struct qlcnic_sriov *sriov;

	sriov = adapter->ahw->sriov;

	if (!vf->sriov_vlans)
		return;

	spin_lock_bh(&vf->vlan_list_lock);

	switch (opcode) {
	case QLC_VLAN_ADD:
		qlcnic_sriov_add_vlan_id(sriov, vf, vlan_id);
		break;
	case QLC_VLAN_DELETE:
		qlcnic_sriov_del_vlan_id(sriov, vf, vlan_id);
		break;
	default:
		netdev_err(adapter->netdev, "Invalid VLAN operation\n");
	}

	spin_unlock_bh(&vf->vlan_list_lock);
	return;
}

int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter,
				   u16 vid, u8 enable)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct net_device *netdev = adapter->netdev;
	struct qlcnic_vf_info *vf;
	struct qlcnic_cmd_args cmd;
	int ret;

	memset(&cmd, 0, sizeof(cmd));
	if (vid == 0)
		return 0;

	vf = &adapter->ahw->sriov->vf_info[0];
	ret = qlcnic_sriov_validate_vlan_cfg(adapter, vid, enable);
	if (ret)
		return ret;

	ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd,
					     QLCNIC_BC_CMD_CFG_GUEST_VLAN);
	if (ret)
		return ret;

	cmd.req.arg[1] = (enable & 1) | vid << 16;

	qlcnic_sriov_cleanup_async_list(&sriov->bc);
	ret = qlcnic_issue_cmd(adapter, &cmd);
	if (ret) {
		dev_err(&adapter->pdev->dev,
			"Failed to configure guest VLAN, err=%d\n", ret);
	} else {
		netif_addr_lock_bh(netdev);
		qlcnic_free_mac_list(adapter);
		netif_addr_unlock_bh(netdev);

		if (enable)
			qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD);
		else
			qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE);

		netif_addr_lock_bh(netdev);
		qlcnic_set_multi(netdev);
		netif_addr_unlock_bh(netdev);
	}

	qlcnic_free_mbx_args(&cmd);
	return ret;
}

static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter)
{
	struct list_head *head = &adapter->mac_list;
	struct qlcnic_mac_vlan_list *cur;

	while (!list_empty(head)) {
		cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list);
		qlcnic_sre_macaddr_change(adapter, cur->mac_addr, cur->vlan_id,
					  QLCNIC_MAC_DEL);
		list_del(&cur->list);
		kfree(cur);
	}
}


static int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev)
{
	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
	struct net_device *netdev = adapter->netdev;
	int retval;

	netif_device_detach(netdev);
	qlcnic_cancel_idc_work(adapter);

	if (netif_running(netdev))
		qlcnic_down(adapter, netdev);

	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);
	qlcnic_sriov_cfg_bc_intr(adapter, 0);
	qlcnic_83xx_disable_mbx_intr(adapter);
	cancel_delayed_work_sync(&adapter->idc_aen_work);

	retval = pci_save_state(pdev);
	if (retval)
		return retval;

	return 0;
}

static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)
{
	struct qlc_83xx_idc *idc = &adapter->ahw->idc;
	struct net_device *netdev = adapter->netdev;
	int err;

	set_bit(QLC_83XX_MODULE_LOADED, &idc->status);
	qlcnic_83xx_enable_mbx_interrupt(adapter);
	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
	if (err)
		return err;

	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);
	if (!err) {
		if (netif_running(netdev)) {
			err = qlcnic_up(adapter, netdev);
			if (!err)
				qlcnic_restore_indev_addr(netdev, NETDEV_UP);
		}
	}

	netif_device_attach(netdev);
	qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,
			     idc->delay);
	return err;
}

int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_vf_info *vf;
	int i;

	for (i = 0; i < sriov->num_vfs; i++) {
		vf = &sriov->vf_info[i];
		vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans,
					  sizeof(*vf->sriov_vlans), GFP_KERNEL);
		if (!vf->sriov_vlans)
			return -ENOMEM;
	}

	return 0;
}

void qlcnic_sriov_free_vlans(struct qlcnic_adapter *adapter)
{
	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
	struct qlcnic_vf_info *vf;
	int i;

	for (i = 0; i < sriov->num_vfs; i++) {
		vf = &sriov->vf_info[i];
		kfree(vf->sriov_vlans);
		vf->sriov_vlans = NULL;
	}
}

void qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *sriov,
			      struct qlcnic_vf_info *vf, u16 vlan_id)
{
	int i;

	for (i = 0; i < sriov->num_allowed_vlans; i++) {
		if (!vf->sriov_vlans[i]) {
			vf->sriov_vlans[i] = vlan_id;
			vf->num_vlan++;
			return;
		}
	}
}

void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *sriov,
			      struct qlcnic_vf_info *vf, u16 vlan_id)
{
	int i;

	for (i = 0; i < sriov->num_allowed_vlans; i++) {
		if (vf->sriov_vlans[i] == vlan_id) {
			vf->sriov_vlans[i] = 0;
			vf->num_vlan--;
			return;
		}
	}
}

bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf)
{
	bool err = false;

	spin_lock_bh(&vf->vlan_list_lock);

	if (vf->num_vlan)
		err = true;

	spin_unlock_bh(&vf->vlan_list_lock);
	return err;
}
