/*
 * Copyright (C) 2015 Cavium, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/log2.h>
#include <linux/prefetch.h>
#include <linux/irq.h>
#include <linux/iommu.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/filter.h>
#include <linux/net_tstamp.h>
#include <linux/workqueue.h>

#include "nic_reg.h"
#include "nic.h"
#include "nicvf_queues.h"
#include "thunder_bgx.h"
#include "../common/cavium_ptp.h"

#define DRV_NAME	"nicvf"
#define DRV_VERSION	"1.0"

/* NOTE: Packets bigger than 1530 are split across multiple pages and XDP needs
 * the buffer to be contiguous. Allow XDP to be set up only if we don't exceed
 * this value, keeping headroom for the 14 byte Ethernet header and two
 * VLAN tags (for QinQ)
 */
#define MAX_XDP_MTU	(1530 - ETH_HLEN - VLAN_HLEN * 2)

/* Supported devices */
static const struct pci_device_id nicvf_id_table[] = {
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
			 PCI_DEVICE_ID_THUNDER_NIC_VF,
			 PCI_VENDOR_ID_CAVIUM,
			 PCI_SUBSYS_DEVID_88XX_NIC_VF) },
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
			 PCI_DEVICE_ID_THUNDER_PASS1_NIC_VF,
			 PCI_VENDOR_ID_CAVIUM,
			 PCI_SUBSYS_DEVID_88XX_PASS1_NIC_VF) },
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
			 PCI_DEVICE_ID_THUNDER_NIC_VF,
			 PCI_VENDOR_ID_CAVIUM,
			 PCI_SUBSYS_DEVID_81XX_NIC_VF) },
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
			 PCI_DEVICE_ID_THUNDER_NIC_VF,
			 PCI_VENDOR_ID_CAVIUM,
			 PCI_SUBSYS_DEVID_83XX_NIC_VF) },
	{ 0, }  /* end of table */
};

MODULE_AUTHOR("Sunil Goutham");
MODULE_DESCRIPTION("Cavium Thunder NIC Virtual Function Driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, nicvf_id_table);

static int debug = 0x00;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug message level bitmap");

static int cpi_alg = CPI_ALG_NONE;
module_param(cpi_alg, int, 0444);
MODULE_PARM_DESC(cpi_alg,
		 "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)");

static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx)
{
	if (nic->sqs_mode)
		return qidx + ((nic->sqs_id + 1) * MAX_CMP_QUEUES_PER_QS);
	else
		return qidx;
}

/* The Cavium ThunderX network controller can *only* be found in SoCs
 * containing the ThunderX ARM64 CPU implementation.  All accesses to the device
 * registers on this platform are implicitly strongly ordered with respect
 * to memory accesses. So writeq_relaxed() and readq_relaxed() are safe to use
 * with no memory barriers in this driver.  The readq()/writeq() functions add
 * explicit ordering operation which in this case are redundant, and only
 * add overhead.
 */

/* Register read/write APIs */
void nicvf_reg_write(struct nicvf *nic, u64 offset, u64 val)
{
	writeq_relaxed(val, nic->reg_base + offset);
}

u64 nicvf_reg_read(struct nicvf *nic, u64 offset)
{
	return readq_relaxed(nic->reg_base + offset);
}

void nicvf_queue_reg_write(struct nicvf *nic, u64 offset,
			   u64 qidx, u64 val)
{
	void __iomem *addr = nic->reg_base + offset;

	writeq_relaxed(val, addr + (qidx << NIC_Q_NUM_SHIFT));
}

u64 nicvf_queue_reg_read(struct nicvf *nic, u64 offset, u64 qidx)
{
	void __iomem *addr = nic->reg_base + offset;

	return readq_relaxed(addr + (qidx << NIC_Q_NUM_SHIFT));
}

/* VF -> PF mailbox communication */
static void nicvf_write_to_mbx(struct nicvf *nic, union nic_mbx *mbx)
{
	u64 *msg = (u64 *)mbx;

	nicvf_reg_write(nic, NIC_VF_PF_MAILBOX_0_1 + 0, msg[0]);
	nicvf_reg_write(nic, NIC_VF_PF_MAILBOX_0_1 + 8, msg[1]);
}

int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
{
	int timeout = NIC_MBOX_MSG_TIMEOUT;
	int sleep = 10;
	int ret = 0;

	mutex_lock(&nic->rx_mode_mtx);

	nic->pf_acked = false;
	nic->pf_nacked = false;

	nicvf_write_to_mbx(nic, mbx);

	/* Wait for previous message to be acked, timeout 2sec */
	while (!nic->pf_acked) {
		if (nic->pf_nacked) {
			netdev_err(nic->netdev,
				   "PF NACK to mbox msg 0x%02x from VF%d\n",
				   (mbx->msg.msg & 0xFF), nic->vf_id);
			ret = -EINVAL;
			break;
		}
		msleep(sleep);
		if (nic->pf_acked)
			break;
		timeout -= sleep;
		if (!timeout) {
			netdev_err(nic->netdev,
				   "PF didn't ACK to mbox msg 0x%02x from VF%d\n",
				   (mbx->msg.msg & 0xFF), nic->vf_id);
			ret = -EBUSY;
			break;
		}
	}
	mutex_unlock(&nic->rx_mode_mtx);
	return ret;
}

/* Checks if VF is able to comminicate with PF
* and also gets the VNIC number this VF is associated to.
*/
static int nicvf_check_pf_ready(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.msg.msg = NIC_MBOX_MSG_READY;
	if (nicvf_send_msg_to_pf(nic, &mbx)) {
		netdev_err(nic->netdev,
			   "PF didn't respond to READY msg\n");
		return 0;
	}

	return 1;
}

static void nicvf_send_cfg_done(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.msg.msg = NIC_MBOX_MSG_CFG_DONE;
	if (nicvf_send_msg_to_pf(nic, &mbx)) {
		netdev_err(nic->netdev,
			   "PF didn't respond to CFG DONE msg\n");
	}
}

static void nicvf_read_bgx_stats(struct nicvf *nic, struct bgx_stats_msg *bgx)
{
	if (bgx->rx)
		nic->bgx_stats.rx_stats[bgx->idx] = bgx->stats;
	else
		nic->bgx_stats.tx_stats[bgx->idx] = bgx->stats;
}

static void  nicvf_handle_mbx_intr(struct nicvf *nic)
{
	union nic_mbx mbx = {};
	u64 *mbx_data;
	u64 mbx_addr;
	int i;

	mbx_addr = NIC_VF_PF_MAILBOX_0_1;
	mbx_data = (u64 *)&mbx;

	for (i = 0; i < NIC_PF_VF_MAILBOX_SIZE; i++) {
		*mbx_data = nicvf_reg_read(nic, mbx_addr);
		mbx_data++;
		mbx_addr += sizeof(u64);
	}

	netdev_dbg(nic->netdev, "Mbox message: msg: 0x%x\n", mbx.msg.msg);
	switch (mbx.msg.msg) {
	case NIC_MBOX_MSG_READY:
		nic->pf_acked = true;
		nic->vf_id = mbx.nic_cfg.vf_id & 0x7F;
		nic->tns_mode = mbx.nic_cfg.tns_mode & 0x7F;
		nic->node = mbx.nic_cfg.node_id;
		if (!nic->set_mac_pending)
			ether_addr_copy(nic->netdev->dev_addr,
					mbx.nic_cfg.mac_addr);
		nic->sqs_mode = mbx.nic_cfg.sqs_mode;
		nic->loopback_supported = mbx.nic_cfg.loopback_supported;
		nic->link_up = false;
		nic->duplex = 0;
		nic->speed = 0;
		break;
	case NIC_MBOX_MSG_ACK:
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_NACK:
		nic->pf_nacked = true;
		break;
	case NIC_MBOX_MSG_RSS_SIZE:
		nic->rss_info.rss_size = mbx.rss_size.ind_tbl_size;
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_BGX_STATS:
		nicvf_read_bgx_stats(nic, &mbx.bgx_stats);
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_BGX_LINK_CHANGE:
		nic->pf_acked = true;
		if (nic->link_up != mbx.link_status.link_up) {
			nic->link_up = mbx.link_status.link_up;
			nic->duplex = mbx.link_status.duplex;
			nic->speed = mbx.link_status.speed;
			nic->mac_type = mbx.link_status.mac_type;
			if (nic->link_up) {
				netdev_info(nic->netdev,
					    "Link is Up %d Mbps %s duplex\n",
					    nic->speed,
					    nic->duplex == DUPLEX_FULL ?
					    "Full" : "Half");
				netif_carrier_on(nic->netdev);
				netif_tx_start_all_queues(nic->netdev);
			} else {
				netdev_info(nic->netdev, "Link is Down\n");
				netif_carrier_off(nic->netdev);
				netif_tx_stop_all_queues(nic->netdev);
			}
		}
		break;
	case NIC_MBOX_MSG_ALLOC_SQS:
		nic->sqs_count = mbx.sqs_alloc.qs_count;
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_SNICVF_PTR:
		/* Primary VF: make note of secondary VF's pointer
		 * to be used while packet transmission.
		 */
		nic->snicvf[mbx.nicvf.sqs_id] =
			(struct nicvf *)mbx.nicvf.nicvf;
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_PNICVF_PTR:
		/* Secondary VF/Qset: make note of primary VF's pointer
		 * to be used while packet reception, to handover packet
		 * to primary VF's netdev.
		 */
		nic->pnicvf = (struct nicvf *)mbx.nicvf.nicvf;
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_PFC:
		nic->pfc.autoneg = mbx.pfc.autoneg;
		nic->pfc.fc_rx = mbx.pfc.fc_rx;
		nic->pfc.fc_tx = mbx.pfc.fc_tx;
		nic->pf_acked = true;
		break;
	default:
		netdev_err(nic->netdev,
			   "Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
		break;
	}
	nicvf_clear_intr(nic, NICVF_INTR_MBOX, 0);
}

static int nicvf_hw_set_mac_addr(struct nicvf *nic, struct net_device *netdev)
{
	union nic_mbx mbx = {};

	mbx.mac.msg = NIC_MBOX_MSG_SET_MAC;
	mbx.mac.vf_id = nic->vf_id;
	ether_addr_copy(mbx.mac.mac_addr, netdev->dev_addr);

	return nicvf_send_msg_to_pf(nic, &mbx);
}

static void nicvf_config_cpi(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.cpi_cfg.msg = NIC_MBOX_MSG_CPI_CFG;
	mbx.cpi_cfg.vf_id = nic->vf_id;
	mbx.cpi_cfg.cpi_alg = nic->cpi_alg;
	mbx.cpi_cfg.rq_cnt = nic->qs->rq_cnt;

	nicvf_send_msg_to_pf(nic, &mbx);
}

static void nicvf_get_rss_size(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.rss_size.msg = NIC_MBOX_MSG_RSS_SIZE;
	mbx.rss_size.vf_id = nic->vf_id;
	nicvf_send_msg_to_pf(nic, &mbx);
}

void nicvf_config_rss(struct nicvf *nic)
{
	union nic_mbx mbx = {};
	struct nicvf_rss_info *rss = &nic->rss_info;
	int ind_tbl_len = rss->rss_size;
	int i, nextq = 0;

	mbx.rss_cfg.vf_id = nic->vf_id;
	mbx.rss_cfg.hash_bits = rss->hash_bits;
	while (ind_tbl_len) {
		mbx.rss_cfg.tbl_offset = nextq;
		mbx.rss_cfg.tbl_len = min(ind_tbl_len,
					       RSS_IND_TBL_LEN_PER_MBX_MSG);
		mbx.rss_cfg.msg = mbx.rss_cfg.tbl_offset ?
			  NIC_MBOX_MSG_RSS_CFG_CONT : NIC_MBOX_MSG_RSS_CFG;

		for (i = 0; i < mbx.rss_cfg.tbl_len; i++)
			mbx.rss_cfg.ind_tbl[i] = rss->ind_tbl[nextq++];

		nicvf_send_msg_to_pf(nic, &mbx);

		ind_tbl_len -= mbx.rss_cfg.tbl_len;
	}
}

void nicvf_set_rss_key(struct nicvf *nic)
{
	struct nicvf_rss_info *rss = &nic->rss_info;
	u64 key_addr = NIC_VNIC_RSS_KEY_0_4;
	int idx;

	for (idx = 0; idx < RSS_HASH_KEY_SIZE; idx++) {
		nicvf_reg_write(nic, key_addr, rss->key[idx]);
		key_addr += sizeof(u64);
	}
}

static int nicvf_rss_init(struct nicvf *nic)
{
	struct nicvf_rss_info *rss = &nic->rss_info;
	int idx;

	nicvf_get_rss_size(nic);

	if (cpi_alg != CPI_ALG_NONE) {
		rss->enable = false;
		rss->hash_bits = 0;
		return 0;
	}

	rss->enable = true;

	netdev_rss_key_fill(rss->key, RSS_HASH_KEY_SIZE * sizeof(u64));
	nicvf_set_rss_key(nic);

	rss->cfg = RSS_IP_HASH_ENA | RSS_TCP_HASH_ENA | RSS_UDP_HASH_ENA;
	nicvf_reg_write(nic, NIC_VNIC_RSS_CFG, rss->cfg);

	rss->hash_bits =  ilog2(rounddown_pow_of_two(rss->rss_size));

	for (idx = 0; idx < rss->rss_size; idx++)
		rss->ind_tbl[idx] = ethtool_rxfh_indir_default(idx,
							       nic->rx_queues);
	nicvf_config_rss(nic);
	return 1;
}

/* Request PF to allocate additional Qsets */
static void nicvf_request_sqs(struct nicvf *nic)
{
	union nic_mbx mbx = {};
	int sqs;
	int sqs_count = nic->sqs_count;
	int rx_queues = 0, tx_queues = 0;

	/* Only primary VF should request */
	if (nic->sqs_mode ||  !nic->sqs_count)
		return;

	mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
	mbx.sqs_alloc.vf_id = nic->vf_id;
	mbx.sqs_alloc.qs_count = nic->sqs_count;
	if (nicvf_send_msg_to_pf(nic, &mbx)) {
		/* No response from PF */
		nic->sqs_count = 0;
		return;
	}

	/* Return if no Secondary Qsets available */
	if (!nic->sqs_count)
		return;

	if (nic->rx_queues > MAX_RCV_QUEUES_PER_QS)
		rx_queues = nic->rx_queues - MAX_RCV_QUEUES_PER_QS;

	tx_queues = nic->tx_queues + nic->xdp_tx_queues;
	if (tx_queues > MAX_SND_QUEUES_PER_QS)
		tx_queues = tx_queues - MAX_SND_QUEUES_PER_QS;

	/* Set no of Rx/Tx queues in each of the SQsets */
	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
		mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
		mbx.nicvf.vf_id = nic->vf_id;
		mbx.nicvf.sqs_id = sqs;
		nicvf_send_msg_to_pf(nic, &mbx);

		nic->snicvf[sqs]->sqs_id = sqs;
		if (rx_queues > MAX_RCV_QUEUES_PER_QS) {
			nic->snicvf[sqs]->qs->rq_cnt = MAX_RCV_QUEUES_PER_QS;
			rx_queues -= MAX_RCV_QUEUES_PER_QS;
		} else {
			nic->snicvf[sqs]->qs->rq_cnt = rx_queues;
			rx_queues = 0;
		}

		if (tx_queues > MAX_SND_QUEUES_PER_QS) {
			nic->snicvf[sqs]->qs->sq_cnt = MAX_SND_QUEUES_PER_QS;
			tx_queues -= MAX_SND_QUEUES_PER_QS;
		} else {
			nic->snicvf[sqs]->qs->sq_cnt = tx_queues;
			tx_queues = 0;
		}

		nic->snicvf[sqs]->qs->cq_cnt =
		max(nic->snicvf[sqs]->qs->rq_cnt, nic->snicvf[sqs]->qs->sq_cnt);

		/* Initialize secondary Qset's queues and its interrupts */
		nicvf_open(nic->snicvf[sqs]->netdev);
	}

	/* Update stack with actual Rx/Tx queue count allocated */
	if (sqs_count != nic->sqs_count)
		nicvf_set_real_num_queues(nic->netdev,
					  nic->tx_queues, nic->rx_queues);
}

/* Send this Qset's nicvf pointer to PF.
 * PF inturn sends primary VF's nicvf struct to secondary Qsets/VFs
 * so that packets received by these Qsets can use primary VF's netdev
 */
static void nicvf_send_vf_struct(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.nicvf.msg = NIC_MBOX_MSG_NICVF_PTR;
	mbx.nicvf.sqs_mode = nic->sqs_mode;
	mbx.nicvf.nicvf = (u64)nic;
	nicvf_send_msg_to_pf(nic, &mbx);
}

static void nicvf_get_primary_vf_struct(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
	nicvf_send_msg_to_pf(nic, &mbx);
}

int nicvf_set_real_num_queues(struct net_device *netdev,
			      int tx_queues, int rx_queues)
{
	int err = 0;

	err = netif_set_real_num_tx_queues(netdev, tx_queues);
	if (err) {
		netdev_err(netdev,
			   "Failed to set no of Tx queues: %d\n", tx_queues);
		return err;
	}

	err = netif_set_real_num_rx_queues(netdev, rx_queues);
	if (err)
		netdev_err(netdev,
			   "Failed to set no of Rx queues: %d\n", rx_queues);
	return err;
}

static int nicvf_init_resources(struct nicvf *nic)
{
	int err;

	/* Enable Qset */
	nicvf_qset_config(nic, true);

	/* Initialize queues and HW for data transfer */
	err = nicvf_config_data_transfer(nic, true);
	if (err) {
		netdev_err(nic->netdev,
			   "Failed to alloc/config VF's QSet resources\n");
		return err;
	}

	return 0;
}

static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
				struct cqe_rx_t *cqe_rx, struct snd_queue *sq,
				struct rcv_queue *rq, struct sk_buff **skb)
{
	struct xdp_buff xdp;
	struct page *page;
	u32 action;
	u16 len, offset = 0;
	u64 dma_addr, cpu_addr;
	void *orig_data;

	/* Retrieve packet buffer's DMA address and length */
	len = *((u16 *)((void *)cqe_rx + (3 * sizeof(u64))));
	dma_addr = *((u64 *)((void *)cqe_rx + (7 * sizeof(u64))));

	cpu_addr = nicvf_iova_to_phys(nic, dma_addr);
	if (!cpu_addr)
		return false;
	cpu_addr = (u64)phys_to_virt(cpu_addr);
	page = virt_to_page((void *)cpu_addr);

	xdp.data_hard_start = page_address(page);
	xdp.data = (void *)cpu_addr;
	xdp_set_data_meta_invalid(&xdp);
	xdp.data_end = xdp.data + len;
	xdp.rxq = &rq->xdp_rxq;
	orig_data = xdp.data;

	rcu_read_lock();
	action = bpf_prog_run_xdp(prog, &xdp);
	rcu_read_unlock();

	len = xdp.data_end - xdp.data;
	/* Check if XDP program has changed headers */
	if (orig_data != xdp.data) {
		offset = orig_data - xdp.data;
		dma_addr -= offset;
	}

	switch (action) {
	case XDP_PASS:
		/* Check if it's a recycled page, if not
		 * unmap the DMA mapping.
		 *
		 * Recycled page holds an extra reference.
		 */
		if (page_ref_count(page) == 1) {
			dma_addr &= PAGE_MASK;
			dma_unmap_page_attrs(&nic->pdev->dev, dma_addr,
					     RCV_FRAG_LEN + XDP_PACKET_HEADROOM,
					     DMA_FROM_DEVICE,
					     DMA_ATTR_SKIP_CPU_SYNC);
		}

		/* Build SKB and pass on packet to network stack */
		*skb = build_skb(xdp.data,
				 RCV_FRAG_LEN - cqe_rx->align_pad + offset);
		if (!*skb)
			put_page(page);
		else
			skb_put(*skb, len);
		return false;
	case XDP_TX:
		nicvf_xdp_sq_append_pkt(nic, sq, (u64)xdp.data, dma_addr, len);
		return true;
	default:
		bpf_warn_invalid_xdp_action(action);
		/* fall through */
	case XDP_ABORTED:
		trace_xdp_exception(nic->netdev, prog, action);
		/* fall through */
	case XDP_DROP:
		/* Check if it's a recycled page, if not
		 * unmap the DMA mapping.
		 *
		 * Recycled page holds an extra reference.
		 */
		if (page_ref_count(page) == 1) {
			dma_addr &= PAGE_MASK;
			dma_unmap_page_attrs(&nic->pdev->dev, dma_addr,
					     RCV_FRAG_LEN + XDP_PACKET_HEADROOM,
					     DMA_FROM_DEVICE,
					     DMA_ATTR_SKIP_CPU_SYNC);
		}
		put_page(page);
		return true;
	}
	return false;
}

static void nicvf_snd_ptp_handler(struct net_device *netdev,
				  struct cqe_send_t *cqe_tx)
{
	struct nicvf *nic = netdev_priv(netdev);
	struct skb_shared_hwtstamps ts;
	u64 ns;

	nic = nic->pnicvf;

	/* Sync for 'ptp_skb' */
	smp_rmb();

	/* New timestamp request can be queued now */
	atomic_set(&nic->tx_ptp_skbs, 0);

	/* Check for timestamp requested skb */
	if (!nic->ptp_skb)
		return;

	/* Check if timestamping is timedout, which is set to 10us */
	if (cqe_tx->send_status == CQ_TX_ERROP_TSTMP_TIMEOUT ||
	    cqe_tx->send_status == CQ_TX_ERROP_TSTMP_CONFLICT)
		goto no_tstamp;

	/* Get the timestamp */
	memset(&ts, 0, sizeof(ts));
	ns = cavium_ptp_tstamp2time(nic->ptp_clock, cqe_tx->ptp_timestamp);
	ts.hwtstamp = ns_to_ktime(ns);
	skb_tstamp_tx(nic->ptp_skb, &ts);

no_tstamp:
	/* Free the original skb */
	dev_kfree_skb_any(nic->ptp_skb);
	nic->ptp_skb = NULL;
	/* Sync 'ptp_skb' */
	smp_wmb();
}

static void nicvf_snd_pkt_handler(struct net_device *netdev,
				  struct cqe_send_t *cqe_tx,
				  int budget, int *subdesc_cnt,
				  unsigned int *tx_pkts, unsigned int *tx_bytes)
{
	struct sk_buff *skb = NULL;
	struct page *page;
	struct nicvf *nic = netdev_priv(netdev);
	struct snd_queue *sq;
	struct sq_hdr_subdesc *hdr;
	struct sq_hdr_subdesc *tso_sqe;

	sq = &nic->qs->sq[cqe_tx->sq_idx];

	hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, cqe_tx->sqe_ptr);
	if (hdr->subdesc_type != SQ_DESC_TYPE_HEADER)
		return;

	/* Check for errors */
	if (cqe_tx->send_status)
		nicvf_check_cqe_tx_errs(nic->pnicvf, cqe_tx);

	/* Is this a XDP designated Tx queue */
	if (sq->is_xdp) {
		page = (struct page *)sq->xdp_page[cqe_tx->sqe_ptr];
		/* Check if it's recycled page or else unmap DMA mapping */
		if (page && (page_ref_count(page) == 1))
			nicvf_unmap_sndq_buffers(nic, sq, cqe_tx->sqe_ptr,
						 hdr->subdesc_cnt);

		/* Release page reference for recycling */
		if (page)
			put_page(page);
		sq->xdp_page[cqe_tx->sqe_ptr] = (u64)NULL;
		*subdesc_cnt += hdr->subdesc_cnt + 1;
		return;
	}

	skb = (struct sk_buff *)sq->skbuff[cqe_tx->sqe_ptr];
	if (skb) {
		/* Check for dummy descriptor used for HW TSO offload on 88xx */
		if (hdr->dont_send) {
			/* Get actual TSO descriptors and free them */
			tso_sqe =
			 (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2);
			nicvf_unmap_sndq_buffers(nic, sq, hdr->rsvd2,
						 tso_sqe->subdesc_cnt);
			*subdesc_cnt += tso_sqe->subdesc_cnt + 1;
		} else {
			nicvf_unmap_sndq_buffers(nic, sq, cqe_tx->sqe_ptr,
						 hdr->subdesc_cnt);
		}
		*subdesc_cnt += hdr->subdesc_cnt + 1;
		prefetch(skb);
		(*tx_pkts)++;
		*tx_bytes += skb->len;
		/* If timestamp is requested for this skb, don't free it */
		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
		    !nic->pnicvf->ptp_skb)
			nic->pnicvf->ptp_skb = skb;
		else
			napi_consume_skb(skb, budget);
		sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL;
	} else {
		/* In case of SW TSO on 88xx, only last segment will have
		 * a SKB attached, so just free SQEs here.
		 */
		if (!nic->hw_tso)
			*subdesc_cnt += hdr->subdesc_cnt + 1;
	}
}

static inline void nicvf_set_rxhash(struct net_device *netdev,
				    struct cqe_rx_t *cqe_rx,
				    struct sk_buff *skb)
{
	u8 hash_type;
	u32 hash;

	if (!(netdev->features & NETIF_F_RXHASH))
		return;

	switch (cqe_rx->rss_alg) {
	case RSS_ALG_TCP_IP:
	case RSS_ALG_UDP_IP:
		hash_type = PKT_HASH_TYPE_L4;
		hash = cqe_rx->rss_tag;
		break;
	case RSS_ALG_IP:
		hash_type = PKT_HASH_TYPE_L3;
		hash = cqe_rx->rss_tag;
		break;
	default:
		hash_type = PKT_HASH_TYPE_NONE;
		hash = 0;
	}

	skb_set_hash(skb, hash, hash_type);
}

static inline void nicvf_set_rxtstamp(struct nicvf *nic, struct sk_buff *skb)
{
	u64 ns;

	if (!nic->ptp_clock || !nic->hw_rx_tstamp)
		return;

	/* The first 8 bytes is the timestamp */
	ns = cavium_ptp_tstamp2time(nic->ptp_clock,
				    be64_to_cpu(*(__be64 *)skb->data));
	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);

	__skb_pull(skb, 8);
}

static void nicvf_rcv_pkt_handler(struct net_device *netdev,
				  struct napi_struct *napi,
				  struct cqe_rx_t *cqe_rx,
				  struct snd_queue *sq, struct rcv_queue *rq)
{
	struct sk_buff *skb = NULL;
	struct nicvf *nic = netdev_priv(netdev);
	struct nicvf *snic = nic;
	int err = 0;
	int rq_idx;

	rq_idx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx);

	if (nic->sqs_mode) {
		/* Use primary VF's 'nicvf' struct */
		nic = nic->pnicvf;
		netdev = nic->netdev;
	}

	/* Check for errors */
	if (cqe_rx->err_level || cqe_rx->err_opcode) {
		err = nicvf_check_cqe_rx_errs(nic, cqe_rx);
		if (err && !cqe_rx->rb_cnt)
			return;
	}

	/* For XDP, ignore pkts spanning multiple pages */
	if (nic->xdp_prog && (cqe_rx->rb_cnt == 1)) {
		/* Packet consumed by XDP */
		if (nicvf_xdp_rx(snic, nic->xdp_prog, cqe_rx, sq, rq, &skb))
			return;
	} else {
		skb = nicvf_get_rcv_skb(snic, cqe_rx,
					nic->xdp_prog ? true : false);
	}

	if (!skb)
		return;

	if (netif_msg_pktdata(nic)) {
		netdev_info(nic->netdev, "skb 0x%p, len=%d\n", skb, skb->len);
		print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
			       skb->data, skb->len, true);
	}

	/* If error packet, drop it here */
	if (err) {
		dev_kfree_skb_any(skb);
		return;
	}

	nicvf_set_rxtstamp(nic, skb);
	nicvf_set_rxhash(netdev, cqe_rx, skb);

	skb_record_rx_queue(skb, rq_idx);
	if (netdev->hw_features & NETIF_F_RXCSUM) {
		/* HW by default verifies TCP/UDP/SCTP checksums */
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	} else {
		skb_checksum_none_assert(skb);
	}

	skb->protocol = eth_type_trans(skb, netdev);

	/* Check for stripped VLAN */
	if (cqe_rx->vlan_found && cqe_rx->vlan_stripped)
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
				       ntohs((__force __be16)cqe_rx->vlan_tci));

	if (napi && (netdev->features & NETIF_F_GRO))
		napi_gro_receive(napi, skb);
	else
		netif_receive_skb(skb);
}

static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
				 struct napi_struct *napi, int budget)
{
	int processed_cqe, work_done = 0, tx_done = 0;
	int cqe_count, cqe_head;
	int subdesc_cnt = 0;
	struct nicvf *nic = netdev_priv(netdev);
	struct queue_set *qs = nic->qs;
	struct cmp_queue *cq = &qs->cq[cq_idx];
	struct cqe_rx_t *cq_desc;
	struct netdev_queue *txq;
	struct snd_queue *sq = &qs->sq[cq_idx];
	struct rcv_queue *rq = &qs->rq[cq_idx];
	unsigned int tx_pkts = 0, tx_bytes = 0, txq_idx;

	spin_lock_bh(&cq->lock);
loop:
	processed_cqe = 0;
	/* Get no of valid CQ entries to process */
	cqe_count = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS, cq_idx);
	cqe_count &= CQ_CQE_COUNT;
	if (!cqe_count)
		goto done;

	/* Get head of the valid CQ entries */
	cqe_head = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, cq_idx) >> 9;
	cqe_head &= 0xFFFF;

	while (processed_cqe < cqe_count) {
		/* Get the CQ descriptor */
		cq_desc = (struct cqe_rx_t *)GET_CQ_DESC(cq, cqe_head);
		cqe_head++;
		cqe_head &= (cq->dmem.q_len - 1);
		/* Initiate prefetch for next descriptor */
		prefetch((struct cqe_rx_t *)GET_CQ_DESC(cq, cqe_head));

		if ((work_done >= budget) && napi &&
		    (cq_desc->cqe_type != CQE_TYPE_SEND)) {
			break;
		}

		switch (cq_desc->cqe_type) {
		case CQE_TYPE_RX:
			nicvf_rcv_pkt_handler(netdev, napi, cq_desc, sq, rq);
			work_done++;
		break;
		case CQE_TYPE_SEND:
			nicvf_snd_pkt_handler(netdev, (void *)cq_desc,
					      budget, &subdesc_cnt,
					      &tx_pkts, &tx_bytes);
			tx_done++;
		break;
		case CQE_TYPE_SEND_PTP:
			nicvf_snd_ptp_handler(netdev, (void *)cq_desc);
		break;
		case CQE_TYPE_INVALID:
		case CQE_TYPE_RX_SPLIT:
		case CQE_TYPE_RX_TCP:
			/* Ignore for now */
		break;
		}
		processed_cqe++;
	}

	/* Ring doorbell to inform H/W to reuse processed CQEs */
	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_DOOR,
			      cq_idx, processed_cqe);

	if ((work_done < budget) && napi)
		goto loop;

done:
	/* Update SQ's descriptor free count */
	if (subdesc_cnt)
		nicvf_put_sq_desc(sq, subdesc_cnt);

	txq_idx = nicvf_netdev_qidx(nic, cq_idx);
	/* Handle XDP TX queues */
	if (nic->pnicvf->xdp_prog) {
		if (txq_idx < nic->pnicvf->xdp_tx_queues) {
			nicvf_xdp_sq_doorbell(nic, sq, cq_idx);
			goto out;
		}
		nic = nic->pnicvf;
		txq_idx -= nic->pnicvf->xdp_tx_queues;
	}

	/* Wakeup TXQ if its stopped earlier due to SQ full */
	if (tx_done ||
	    (atomic_read(&sq->free_cnt) >= MIN_SQ_DESC_PER_PKT_XMIT)) {
		netdev = nic->pnicvf->netdev;
		txq = netdev_get_tx_queue(netdev, txq_idx);
		if (tx_pkts)
			netdev_tx_completed_queue(txq, tx_pkts, tx_bytes);

		/* To read updated queue and carrier status */
		smp_mb();
		if (netif_tx_queue_stopped(txq) && netif_carrier_ok(netdev)) {
			netif_tx_wake_queue(txq);
			nic = nic->pnicvf;
			this_cpu_inc(nic->drv_stats->txq_wake);
			netif_warn(nic, tx_err, netdev,
				   "Transmit queue wakeup SQ%d\n", txq_idx);
		}
	}

out:
	spin_unlock_bh(&cq->lock);
	return work_done;
}

static int nicvf_poll(struct napi_struct *napi, int budget)
{
	u64  cq_head;
	int  work_done = 0;
	struct net_device *netdev = napi->dev;
	struct nicvf *nic = netdev_priv(netdev);
	struct nicvf_cq_poll *cq;

	cq = container_of(napi, struct nicvf_cq_poll, napi);
	work_done = nicvf_cq_intr_handler(netdev, cq->cq_idx, napi, budget);

	if (work_done < budget) {
		/* Slow packet rate, exit polling */
		napi_complete_done(napi, work_done);
		/* Re-enable interrupts */
		cq_head = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD,
					       cq->cq_idx);
		nicvf_clear_intr(nic, NICVF_INTR_CQ, cq->cq_idx);
		nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_HEAD,
				      cq->cq_idx, cq_head);
		nicvf_enable_intr(nic, NICVF_INTR_CQ, cq->cq_idx);
	}
	return work_done;
}

/* Qset error interrupt handler
 *
 * As of now only CQ errors are handled
 */
static void nicvf_handle_qs_err(unsigned long data)
{
	struct nicvf *nic = (struct nicvf *)data;
	struct queue_set *qs = nic->qs;
	int qidx;
	u64 status;

	netif_tx_disable(nic->netdev);

	/* Check if it is CQ err */
	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
		status = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS,
					      qidx);
		if (!(status & CQ_ERR_MASK))
			continue;
		/* Process already queued CQEs and reconfig CQ */
		nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
		nicvf_sq_disable(nic, qidx);
		nicvf_cq_intr_handler(nic->netdev, qidx, NULL, 0);
		nicvf_cmp_queue_config(nic, qs, qidx, true);
		nicvf_sq_free_used_descs(nic->netdev, &qs->sq[qidx], qidx);
		nicvf_sq_enable(nic, &qs->sq[qidx], qidx);

		nicvf_enable_intr(nic, NICVF_INTR_CQ, qidx);
	}

	netif_tx_start_all_queues(nic->netdev);
	/* Re-enable Qset error interrupt */
	nicvf_enable_intr(nic, NICVF_INTR_QS_ERR, 0);
}

static void nicvf_dump_intr_status(struct nicvf *nic)
{
	netif_info(nic, intr, nic->netdev, "interrupt status 0x%llx\n",
		   nicvf_reg_read(nic, NIC_VF_INT));
}

static irqreturn_t nicvf_misc_intr_handler(int irq, void *nicvf_irq)
{
	struct nicvf *nic = (struct nicvf *)nicvf_irq;
	u64 intr;

	nicvf_dump_intr_status(nic);

	intr = nicvf_reg_read(nic, NIC_VF_INT);
	/* Check for spurious interrupt */
	if (!(intr & NICVF_INTR_MBOX_MASK))
		return IRQ_HANDLED;

	nicvf_handle_mbx_intr(nic);

	return IRQ_HANDLED;
}

static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
{
	struct nicvf_cq_poll *cq_poll = (struct nicvf_cq_poll *)cq_irq;
	struct nicvf *nic = cq_poll->nicvf;
	int qidx = cq_poll->cq_idx;

	nicvf_dump_intr_status(nic);

	/* Disable interrupts */
	nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);

	/* Schedule NAPI */
	napi_schedule_irqoff(&cq_poll->napi);

	/* Clear interrupt */
	nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);

	return IRQ_HANDLED;
}

static irqreturn_t nicvf_rbdr_intr_handler(int irq, void *nicvf_irq)
{
	struct nicvf *nic = (struct nicvf *)nicvf_irq;
	u8 qidx;


	nicvf_dump_intr_status(nic);

	/* Disable RBDR interrupt and schedule softirq */
	for (qidx = 0; qidx < nic->qs->rbdr_cnt; qidx++) {
		if (!nicvf_is_intr_enabled(nic, NICVF_INTR_RBDR, qidx))
			continue;
		nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
		tasklet_hi_schedule(&nic->rbdr_task);
		/* Clear interrupt */
		nicvf_clear_intr(nic, NICVF_INTR_RBDR, qidx);
	}

	return IRQ_HANDLED;
}

static irqreturn_t nicvf_qs_err_intr_handler(int irq, void *nicvf_irq)
{
	struct nicvf *nic = (struct nicvf *)nicvf_irq;

	nicvf_dump_intr_status(nic);

	/* Disable Qset err interrupt and schedule softirq */
	nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
	tasklet_hi_schedule(&nic->qs_err_task);
	nicvf_clear_intr(nic, NICVF_INTR_QS_ERR, 0);

	return IRQ_HANDLED;
}

static void nicvf_set_irq_affinity(struct nicvf *nic)
{
	int vec, cpu;

	for (vec = 0; vec < nic->num_vec; vec++) {
		if (!nic->irq_allocated[vec])
			continue;

		if (!zalloc_cpumask_var(&nic->affinity_mask[vec], GFP_KERNEL))
			return;
		 /* CQ interrupts */
		if (vec < NICVF_INTR_ID_SQ)
			/* Leave CPU0 for RBDR and other interrupts */
			cpu = nicvf_netdev_qidx(nic, vec) + 1;
		else
			cpu = 0;

		cpumask_set_cpu(cpumask_local_spread(cpu, nic->node),
				nic->affinity_mask[vec]);
		irq_set_affinity_hint(pci_irq_vector(nic->pdev, vec),
				      nic->affinity_mask[vec]);
	}
}

static int nicvf_register_interrupts(struct nicvf *nic)
{
	int irq, ret = 0;

	for_each_cq_irq(irq)
		sprintf(nic->irq_name[irq], "%s-rxtx-%d",
			nic->pnicvf->netdev->name,
			nicvf_netdev_qidx(nic, irq));

	for_each_sq_irq(irq)
		sprintf(nic->irq_name[irq], "%s-sq-%d",
			nic->pnicvf->netdev->name,
			nicvf_netdev_qidx(nic, irq - NICVF_INTR_ID_SQ));

	for_each_rbdr_irq(irq)
		sprintf(nic->irq_name[irq], "%s-rbdr-%d",
			nic->pnicvf->netdev->name,
			nic->sqs_mode ? (nic->sqs_id + 1) : 0);

	/* Register CQ interrupts */
	for (irq = 0; irq < nic->qs->cq_cnt; irq++) {
		ret = request_irq(pci_irq_vector(nic->pdev, irq),
				  nicvf_intr_handler,
				  0, nic->irq_name[irq], nic->napi[irq]);
		if (ret)
			goto err;
		nic->irq_allocated[irq] = true;
	}

	/* Register RBDR interrupt */
	for (irq = NICVF_INTR_ID_RBDR;
	     irq < (NICVF_INTR_ID_RBDR + nic->qs->rbdr_cnt); irq++) {
		ret = request_irq(pci_irq_vector(nic->pdev, irq),
				  nicvf_rbdr_intr_handler,
				  0, nic->irq_name[irq], nic);
		if (ret)
			goto err;
		nic->irq_allocated[irq] = true;
	}

	/* Register QS error interrupt */
	sprintf(nic->irq_name[NICVF_INTR_ID_QS_ERR], "%s-qset-err-%d",
		nic->pnicvf->netdev->name,
		nic->sqs_mode ? (nic->sqs_id + 1) : 0);
	irq = NICVF_INTR_ID_QS_ERR;
	ret = request_irq(pci_irq_vector(nic->pdev, irq),
			  nicvf_qs_err_intr_handler,
			  0, nic->irq_name[irq], nic);
	if (ret)
		goto err;

	nic->irq_allocated[irq] = true;

	/* Set IRQ affinities */
	nicvf_set_irq_affinity(nic);

err:
	if (ret)
		netdev_err(nic->netdev, "request_irq failed, vector %d\n", irq);

	return ret;
}

static void nicvf_unregister_interrupts(struct nicvf *nic)
{
	struct pci_dev *pdev = nic->pdev;
	int irq;

	/* Free registered interrupts */
	for (irq = 0; irq < nic->num_vec; irq++) {
		if (!nic->irq_allocated[irq])
			continue;

		irq_set_affinity_hint(pci_irq_vector(pdev, irq), NULL);
		free_cpumask_var(nic->affinity_mask[irq]);

		if (irq < NICVF_INTR_ID_SQ)
			free_irq(pci_irq_vector(pdev, irq), nic->napi[irq]);
		else
			free_irq(pci_irq_vector(pdev, irq), nic);

		nic->irq_allocated[irq] = false;
	}

	/* Disable MSI-X */
	pci_free_irq_vectors(pdev);
	nic->num_vec = 0;
}

/* Initialize MSIX vectors and register MISC interrupt.
 * Send READY message to PF to check if its alive
 */
static int nicvf_register_misc_interrupt(struct nicvf *nic)
{
	int ret = 0;
	int irq = NICVF_INTR_ID_MISC;

	/* Return if mailbox interrupt is already registered */
	if (nic->pdev->msix_enabled)
		return 0;

	/* Enable MSI-X */
	nic->num_vec = pci_msix_vec_count(nic->pdev);
	ret = pci_alloc_irq_vectors(nic->pdev, nic->num_vec, nic->num_vec,
				    PCI_IRQ_MSIX);
	if (ret < 0) {
		netdev_err(nic->netdev,
			   "Req for #%d msix vectors failed\n", nic->num_vec);
		return 1;
	}

	sprintf(nic->irq_name[irq], "%s Mbox", "NICVF");
	/* Register Misc interrupt */
	ret = request_irq(pci_irq_vector(nic->pdev, irq),
			  nicvf_misc_intr_handler, 0, nic->irq_name[irq], nic);

	if (ret)
		return ret;
	nic->irq_allocated[irq] = true;

	/* Enable mailbox interrupt */
	nicvf_enable_intr(nic, NICVF_INTR_MBOX, 0);

	/* Check if VF is able to communicate with PF */
	if (!nicvf_check_pf_ready(nic)) {
		nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
		nicvf_unregister_interrupts(nic);
		return 1;
	}

	return 0;
}

static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
{
	struct nicvf *nic = netdev_priv(netdev);
	int qid = skb_get_queue_mapping(skb);
	struct netdev_queue *txq = netdev_get_tx_queue(netdev, qid);
	struct nicvf *snic;
	struct snd_queue *sq;
	int tmp;

	/* Check for minimum packet length */
	if (skb->len <= ETH_HLEN) {
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	/* In XDP case, initial HW tx queues are used for XDP,
	 * but stack's queue mapping starts at '0', so skip the
	 * Tx queues attached to Rx queues for XDP.
	 */
	if (nic->xdp_prog)
		qid += nic->xdp_tx_queues;

	snic = nic;
	/* Get secondary Qset's SQ structure */
	if (qid >= MAX_SND_QUEUES_PER_QS) {
		tmp = qid / MAX_SND_QUEUES_PER_QS;
		snic = (struct nicvf *)nic->snicvf[tmp - 1];
		if (!snic) {
			netdev_warn(nic->netdev,
				    "Secondary Qset#%d's ptr not initialized\n",
				    tmp - 1);
			dev_kfree_skb(skb);
			return NETDEV_TX_OK;
		}
		qid = qid % MAX_SND_QUEUES_PER_QS;
	}

	sq = &snic->qs->sq[qid];
	if (!netif_tx_queue_stopped(txq) &&
	    !nicvf_sq_append_skb(snic, sq, skb, qid)) {
		netif_tx_stop_queue(txq);

		/* Barrier, so that stop_queue visible to other cpus */
		smp_mb();

		/* Check again, incase another cpu freed descriptors */
		if (atomic_read(&sq->free_cnt) > MIN_SQ_DESC_PER_PKT_XMIT) {
			netif_tx_wake_queue(txq);
		} else {
			this_cpu_inc(nic->drv_stats->txq_stop);
			netif_warn(nic, tx_err, netdev,
				   "Transmit ring full, stopping SQ%d\n", qid);
		}
		return NETDEV_TX_BUSY;
	}

	return NETDEV_TX_OK;
}

static inline void nicvf_free_cq_poll(struct nicvf *nic)
{
	struct nicvf_cq_poll *cq_poll;
	int qidx;

	for (qidx = 0; qidx < nic->qs->cq_cnt; qidx++) {
		cq_poll = nic->napi[qidx];
		if (!cq_poll)
			continue;
		nic->napi[qidx] = NULL;
		kfree(cq_poll);
	}
}

int nicvf_stop(struct net_device *netdev)
{
	int irq, qidx;
	struct nicvf *nic = netdev_priv(netdev);
	struct queue_set *qs = nic->qs;
	struct nicvf_cq_poll *cq_poll = NULL;
	union nic_mbx mbx = {};

	/* wait till all queued set_rx_mode tasks completes */
	if (nic->nicvf_rx_mode_wq) {
		cancel_delayed_work_sync(&nic->link_change_work);
		drain_workqueue(nic->nicvf_rx_mode_wq);
	}

	mbx.msg.msg = NIC_MBOX_MSG_SHUTDOWN;
	nicvf_send_msg_to_pf(nic, &mbx);

	netif_carrier_off(netdev);
	netif_tx_stop_all_queues(nic->netdev);
	nic->link_up = false;

	/* Teardown secondary qsets first */
	if (!nic->sqs_mode) {
		for (qidx = 0; qidx < nic->sqs_count; qidx++) {
			if (!nic->snicvf[qidx])
				continue;
			nicvf_stop(nic->snicvf[qidx]->netdev);
			nic->snicvf[qidx] = NULL;
		}
	}

	/* Disable RBDR & QS error interrupts */
	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
		nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
		nicvf_clear_intr(nic, NICVF_INTR_RBDR, qidx);
	}
	nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
	nicvf_clear_intr(nic, NICVF_INTR_QS_ERR, 0);

	/* Wait for pending IRQ handlers to finish */
	for (irq = 0; irq < nic->num_vec; irq++)
		synchronize_irq(pci_irq_vector(nic->pdev, irq));

	tasklet_kill(&nic->rbdr_task);
	tasklet_kill(&nic->qs_err_task);
	if (nic->rb_work_scheduled)
		cancel_delayed_work_sync(&nic->rbdr_work);

	for (qidx = 0; qidx < nic->qs->cq_cnt; qidx++) {
		cq_poll = nic->napi[qidx];
		if (!cq_poll)
			continue;
		napi_synchronize(&cq_poll->napi);
		/* CQ intr is enabled while napi_complete,
		 * so disable it now
		 */
		nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
		nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
		napi_disable(&cq_poll->napi);
		netif_napi_del(&cq_poll->napi);
	}

	netif_tx_disable(netdev);

	for (qidx = 0; qidx < netdev->num_tx_queues; qidx++)
		netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx));

	/* Free resources */
	nicvf_config_data_transfer(nic, false);

	/* Disable HW Qset */
	nicvf_qset_config(nic, false);

	/* disable mailbox interrupt */
	nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);

	nicvf_unregister_interrupts(nic);

	nicvf_free_cq_poll(nic);

	/* Free any pending SKB saved to receive timestamp */
	if (nic->ptp_skb) {
		dev_kfree_skb_any(nic->ptp_skb);
		nic->ptp_skb = NULL;
	}

	/* Clear multiqset info */
	nic->pnicvf = nic;

	return 0;
}

static int nicvf_config_hw_rx_tstamp(struct nicvf *nic, bool enable)
{
	union nic_mbx mbx = {};

	mbx.ptp.msg = NIC_MBOX_MSG_PTP_CFG;
	mbx.ptp.enable = enable;

	return nicvf_send_msg_to_pf(nic, &mbx);
}

static int nicvf_update_hw_max_frs(struct nicvf *nic, int mtu)
{
	union nic_mbx mbx = {};

	mbx.frs.msg = NIC_MBOX_MSG_SET_MAX_FRS;
	mbx.frs.max_frs = mtu;
	mbx.frs.vf_id = nic->vf_id;

	return nicvf_send_msg_to_pf(nic, &mbx);
}

static void nicvf_link_status_check_task(struct work_struct *work_arg)
{
	struct nicvf *nic = container_of(work_arg,
					 struct nicvf,
					 link_change_work.work);
	union nic_mbx mbx = {};
	mbx.msg.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
	nicvf_send_msg_to_pf(nic, &mbx);
	queue_delayed_work(nic->nicvf_rx_mode_wq,
			   &nic->link_change_work, 2 * HZ);
}

int nicvf_open(struct net_device *netdev)
{
	int cpu, err, qidx;
	struct nicvf *nic = netdev_priv(netdev);
	struct queue_set *qs = nic->qs;
	struct nicvf_cq_poll *cq_poll = NULL;

	/* wait till all queued set_rx_mode tasks completes if any */
	if (nic->nicvf_rx_mode_wq)
		drain_workqueue(nic->nicvf_rx_mode_wq);

	netif_carrier_off(netdev);

	err = nicvf_register_misc_interrupt(nic);
	if (err)
		return err;

	/* Register NAPI handler for processing CQEs */
	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
		cq_poll = kzalloc(sizeof(*cq_poll), GFP_KERNEL);
		if (!cq_poll) {
			err = -ENOMEM;
			goto napi_del;
		}
		cq_poll->cq_idx = qidx;
		cq_poll->nicvf = nic;
		netif_napi_add(netdev, &cq_poll->napi, nicvf_poll,
			       NAPI_POLL_WEIGHT);
		napi_enable(&cq_poll->napi);
		nic->napi[qidx] = cq_poll;
	}

	/* Check if we got MAC address from PF or else generate a radom MAC */
	if (!nic->sqs_mode && is_zero_ether_addr(netdev->dev_addr)) {
		eth_hw_addr_random(netdev);
		nicvf_hw_set_mac_addr(nic, netdev);
	}

	if (nic->set_mac_pending) {
		nic->set_mac_pending = false;
		nicvf_hw_set_mac_addr(nic, netdev);
	}

	/* Init tasklet for handling Qset err interrupt */
	tasklet_init(&nic->qs_err_task, nicvf_handle_qs_err,
		     (unsigned long)nic);

	/* Init RBDR tasklet which will refill RBDR */
	tasklet_init(&nic->rbdr_task, nicvf_rbdr_task,
		     (unsigned long)nic);
	INIT_DELAYED_WORK(&nic->rbdr_work, nicvf_rbdr_work);

	/* Configure CPI alorithm */
	nic->cpi_alg = cpi_alg;
	if (!nic->sqs_mode)
		nicvf_config_cpi(nic);

	nicvf_request_sqs(nic);
	if (nic->sqs_mode)
		nicvf_get_primary_vf_struct(nic);

	/* Configure PTP timestamp */
	if (nic->ptp_clock)
		nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp);
	atomic_set(&nic->tx_ptp_skbs, 0);
	nic->ptp_skb = NULL;

	/* Configure receive side scaling and MTU */
	if (!nic->sqs_mode) {
		nicvf_rss_init(nic);
		err = nicvf_update_hw_max_frs(nic, netdev->mtu);
		if (err)
			goto cleanup;

		/* Clear percpu stats */
		for_each_possible_cpu(cpu)
			memset(per_cpu_ptr(nic->drv_stats, cpu), 0,
			       sizeof(struct nicvf_drv_stats));
	}

	err = nicvf_register_interrupts(nic);
	if (err)
		goto cleanup;

	/* Initialize the queues */
	err = nicvf_init_resources(nic);
	if (err)
		goto cleanup;

	/* Make sure queue initialization is written */
	wmb();

	nicvf_reg_write(nic, NIC_VF_INT, -1);
	/* Enable Qset err interrupt */
	nicvf_enable_intr(nic, NICVF_INTR_QS_ERR, 0);

	/* Enable completion queue interrupt */
	for (qidx = 0; qidx < qs->cq_cnt; qidx++)
		nicvf_enable_intr(nic, NICVF_INTR_CQ, qidx);

	/* Enable RBDR threshold interrupt */
	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++)
		nicvf_enable_intr(nic, NICVF_INTR_RBDR, qidx);

	/* Send VF config done msg to PF */
	nicvf_send_cfg_done(nic);

	if (nic->nicvf_rx_mode_wq) {
		INIT_DELAYED_WORK(&nic->link_change_work,
				  nicvf_link_status_check_task);
		queue_delayed_work(nic->nicvf_rx_mode_wq,
				   &nic->link_change_work, 0);
	}

	return 0;
cleanup:
	nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
	nicvf_unregister_interrupts(nic);
	tasklet_kill(&nic->qs_err_task);
	tasklet_kill(&nic->rbdr_task);
napi_del:
	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
		cq_poll = nic->napi[qidx];
		if (!cq_poll)
			continue;
		napi_disable(&cq_poll->napi);
		netif_napi_del(&cq_poll->napi);
	}
	nicvf_free_cq_poll(nic);
	return err;
}

static int nicvf_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct nicvf *nic = netdev_priv(netdev);
	int orig_mtu = netdev->mtu;

	/* For now just support only the usual MTU sized frames,
	 * plus some headroom for VLAN, QinQ.
	 */
	if (nic->xdp_prog && new_mtu > MAX_XDP_MTU) {
		netdev_warn(netdev, "Jumbo frames not yet supported with XDP, current MTU %d.\n",
			    netdev->mtu);
		return -EINVAL;
	}

	netdev->mtu = new_mtu;

	if (!netif_running(netdev))
		return 0;

	if (nicvf_update_hw_max_frs(nic, new_mtu)) {
		netdev->mtu = orig_mtu;
		return -EINVAL;
	}

	return 0;
}

static int nicvf_set_mac_address(struct net_device *netdev, void *p)
{
	struct sockaddr *addr = p;
	struct nicvf *nic = netdev_priv(netdev);

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);

	if (nic->pdev->msix_enabled) {
		if (nicvf_hw_set_mac_addr(nic, netdev))
			return -EBUSY;
	} else {
		nic->set_mac_pending = true;
	}

	return 0;
}

void nicvf_update_lmac_stats(struct nicvf *nic)
{
	int stat = 0;
	union nic_mbx mbx = {};

	if (!netif_running(nic->netdev))
		return;

	mbx.bgx_stats.msg = NIC_MBOX_MSG_BGX_STATS;
	mbx.bgx_stats.vf_id = nic->vf_id;
	/* Rx stats */
	mbx.bgx_stats.rx = 1;
	while (stat < BGX_RX_STATS_COUNT) {
		mbx.bgx_stats.idx = stat;
		if (nicvf_send_msg_to_pf(nic, &mbx))
			return;
		stat++;
	}

	stat = 0;

	/* Tx stats */
	mbx.bgx_stats.rx = 0;
	while (stat < BGX_TX_STATS_COUNT) {
		mbx.bgx_stats.idx = stat;
		if (nicvf_send_msg_to_pf(nic, &mbx))
			return;
		stat++;
	}
}

void nicvf_update_stats(struct nicvf *nic)
{
	int qidx, cpu;
	u64 tmp_stats = 0;
	struct nicvf_hw_stats *stats = &nic->hw_stats;
	struct nicvf_drv_stats *drv_stats;
	struct queue_set *qs = nic->qs;

#define GET_RX_STATS(reg) \
	nicvf_reg_read(nic, NIC_VNIC_RX_STAT_0_13 | (reg << 3))
#define GET_TX_STATS(reg) \
	nicvf_reg_read(nic, NIC_VNIC_TX_STAT_0_4 | (reg << 3))

	stats->rx_bytes = GET_RX_STATS(RX_OCTS);
	stats->rx_ucast_frames = GET_RX_STATS(RX_UCAST);
	stats->rx_bcast_frames = GET_RX_STATS(RX_BCAST);
	stats->rx_mcast_frames = GET_RX_STATS(RX_MCAST);
	stats->rx_fcs_errors = GET_RX_STATS(RX_FCS);
	stats->rx_l2_errors = GET_RX_STATS(RX_L2ERR);
	stats->rx_drop_red = GET_RX_STATS(RX_RED);
	stats->rx_drop_red_bytes = GET_RX_STATS(RX_RED_OCTS);
	stats->rx_drop_overrun = GET_RX_STATS(RX_ORUN);
	stats->rx_drop_overrun_bytes = GET_RX_STATS(RX_ORUN_OCTS);
	stats->rx_drop_bcast = GET_RX_STATS(RX_DRP_BCAST);
	stats->rx_drop_mcast = GET_RX_STATS(RX_DRP_MCAST);
	stats->rx_drop_l3_bcast = GET_RX_STATS(RX_DRP_L3BCAST);
	stats->rx_drop_l3_mcast = GET_RX_STATS(RX_DRP_L3MCAST);

	stats->tx_bytes = GET_TX_STATS(TX_OCTS);
	stats->tx_ucast_frames = GET_TX_STATS(TX_UCAST);
	stats->tx_bcast_frames = GET_TX_STATS(TX_BCAST);
	stats->tx_mcast_frames = GET_TX_STATS(TX_MCAST);
	stats->tx_drops = GET_TX_STATS(TX_DROP);

	/* On T88 pass 2.0, the dummy SQE added for TSO notification
	 * via CQE has 'dont_send' set. Hence HW drops the pkt pointed
	 * pointed by dummy SQE and results in tx_drops counter being
	 * incremented. Subtracting it from tx_tso counter will give
	 * exact tx_drops counter.
	 */
	if (nic->t88 && nic->hw_tso) {
		for_each_possible_cpu(cpu) {
			drv_stats = per_cpu_ptr(nic->drv_stats, cpu);
			tmp_stats += drv_stats->tx_tso;
		}
		stats->tx_drops = tmp_stats - stats->tx_drops;
	}
	stats->tx_frames = stats->tx_ucast_frames +
			   stats->tx_bcast_frames +
			   stats->tx_mcast_frames;
	stats->rx_frames = stats->rx_ucast_frames +
			   stats->rx_bcast_frames +
			   stats->rx_mcast_frames;
	stats->rx_drops = stats->rx_drop_red +
			  stats->rx_drop_overrun;

	/* Update RQ and SQ stats */
	for (qidx = 0; qidx < qs->rq_cnt; qidx++)
		nicvf_update_rq_stats(nic, qidx);
	for (qidx = 0; qidx < qs->sq_cnt; qidx++)
		nicvf_update_sq_stats(nic, qidx);
}

static void nicvf_get_stats64(struct net_device *netdev,
			      struct rtnl_link_stats64 *stats)
{
	struct nicvf *nic = netdev_priv(netdev);
	struct nicvf_hw_stats *hw_stats = &nic->hw_stats;

	nicvf_update_stats(nic);

	stats->rx_bytes = hw_stats->rx_bytes;
	stats->rx_packets = hw_stats->rx_frames;
	stats->rx_dropped = hw_stats->rx_drops;
	stats->multicast = hw_stats->rx_mcast_frames;

	stats->tx_bytes = hw_stats->tx_bytes;
	stats->tx_packets = hw_stats->tx_frames;
	stats->tx_dropped = hw_stats->tx_drops;

}

static void nicvf_tx_timeout(struct net_device *dev)
{
	struct nicvf *nic = netdev_priv(dev);

	netif_warn(nic, tx_err, dev, "Transmit timed out, resetting\n");

	this_cpu_inc(nic->drv_stats->tx_timeout);
	schedule_work(&nic->reset_task);
}

static void nicvf_reset_task(struct work_struct *work)
{
	struct nicvf *nic;

	nic = container_of(work, struct nicvf, reset_task);

	if (!netif_running(nic->netdev))
		return;

	nicvf_stop(nic->netdev);
	nicvf_open(nic->netdev);
	netif_trans_update(nic->netdev);
}

static int nicvf_config_loopback(struct nicvf *nic,
				 netdev_features_t features)
{
	union nic_mbx mbx = {};

	mbx.lbk.msg = NIC_MBOX_MSG_LOOPBACK;
	mbx.lbk.vf_id = nic->vf_id;
	mbx.lbk.enable = (features & NETIF_F_LOOPBACK) != 0;

	return nicvf_send_msg_to_pf(nic, &mbx);
}

static netdev_features_t nicvf_fix_features(struct net_device *netdev,
					    netdev_features_t features)
{
	struct nicvf *nic = netdev_priv(netdev);

	if ((features & NETIF_F_LOOPBACK) &&
	    netif_running(netdev) && !nic->loopback_supported)
		features &= ~NETIF_F_LOOPBACK;

	return features;
}

static int nicvf_set_features(struct net_device *netdev,
			      netdev_features_t features)
{
	struct nicvf *nic = netdev_priv(netdev);
	netdev_features_t changed = features ^ netdev->features;

	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
		nicvf_config_vlan_stripping(nic, features);

	if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
		return nicvf_config_loopback(nic, features);

	return 0;
}

static void nicvf_set_xdp_queues(struct nicvf *nic, bool bpf_attached)
{
	u8 cq_count, txq_count;

	/* Set XDP Tx queue count same as Rx queue count */
	if (!bpf_attached)
		nic->xdp_tx_queues = 0;
	else
		nic->xdp_tx_queues = nic->rx_queues;

	/* If queue count > MAX_CMP_QUEUES_PER_QS, then additional qsets
	 * needs to be allocated, check how many.
	 */
	txq_count = nic->xdp_tx_queues + nic->tx_queues;
	cq_count = max(nic->rx_queues, txq_count);
	if (cq_count > MAX_CMP_QUEUES_PER_QS) {
		nic->sqs_count = roundup(cq_count, MAX_CMP_QUEUES_PER_QS);
		nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
	} else {
		nic->sqs_count = 0;
	}

	/* Set primary Qset's resources */
	nic->qs->rq_cnt = min_t(u8, nic->rx_queues, MAX_RCV_QUEUES_PER_QS);
	nic->qs->sq_cnt = min_t(u8, txq_count, MAX_SND_QUEUES_PER_QS);
	nic->qs->cq_cnt = max_t(u8, nic->qs->rq_cnt, nic->qs->sq_cnt);

	/* Update stack */
	nicvf_set_real_num_queues(nic->netdev, nic->tx_queues, nic->rx_queues);
}

static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog)
{
	struct net_device *dev = nic->netdev;
	bool if_up = netif_running(nic->netdev);
	struct bpf_prog *old_prog;
	bool bpf_attached = false;
	int ret = 0;

	/* For now just support only the usual MTU sized frames,
	 * plus some headroom for VLAN, QinQ.
	 */
	if (prog && dev->mtu > MAX_XDP_MTU) {
		netdev_warn(dev, "Jumbo frames not yet supported with XDP, current MTU %d.\n",
			    dev->mtu);
		return -EOPNOTSUPP;
	}

	/* ALL SQs attached to CQs i.e same as RQs, are treated as
	 * XDP Tx queues and more Tx queues are allocated for
	 * network stack to send pkts out.
	 *
	 * No of Tx queues are either same as Rx queues or whatever
	 * is left in max no of queues possible.
	 */
	if ((nic->rx_queues + nic->tx_queues) > nic->max_queues) {
		netdev_warn(dev,
			    "Failed to attach BPF prog, RXQs + TXQs > Max %d\n",
			    nic->max_queues);
		return -ENOMEM;
	}

	if (if_up)
		nicvf_stop(nic->netdev);

	old_prog = xchg(&nic->xdp_prog, prog);
	/* Detach old prog, if any */
	if (old_prog)
		bpf_prog_put(old_prog);

	if (nic->xdp_prog) {
		/* Attach BPF program */
		nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1);
		if (!IS_ERR(nic->xdp_prog)) {
			bpf_attached = true;
		} else {
			ret = PTR_ERR(nic->xdp_prog);
			nic->xdp_prog = NULL;
		}
	}

	/* Calculate Tx queues needed for XDP and network stack */
	nicvf_set_xdp_queues(nic, bpf_attached);

	if (if_up) {
		/* Reinitialize interface, clean slate */
		nicvf_open(nic->netdev);
		netif_trans_update(nic->netdev);
	}

	return ret;
}

static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
{
	struct nicvf *nic = netdev_priv(netdev);

	/* To avoid checks while retrieving buffer address from CQE_RX,
	 * do not support XDP for T88 pass1.x silicons which are anyway
	 * not in use widely.
	 */
	if (pass1_silicon(nic->pdev))
		return -EOPNOTSUPP;

	switch (xdp->command) {
	case XDP_SETUP_PROG:
		return nicvf_xdp_setup(nic, xdp->prog);
	case XDP_QUERY_PROG:
		xdp->prog_id = nic->xdp_prog ? nic->xdp_prog->aux->id : 0;
		return 0;
	default:
		return -EINVAL;
	}
}

static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
{
	struct hwtstamp_config config;
	struct nicvf *nic = netdev_priv(netdev);

	if (!nic->ptp_clock)
		return -ENODEV;

	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
		return -EFAULT;

	/* reserved for future extensions */
	if (config.flags)
		return -EINVAL;

	switch (config.tx_type) {
	case HWTSTAMP_TX_OFF:
	case HWTSTAMP_TX_ON:
		break;
	default:
		return -ERANGE;
	}

	switch (config.rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		nic->hw_rx_tstamp = false;
		break;
	case HWTSTAMP_FILTER_ALL:
	case HWTSTAMP_FILTER_SOME:
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
		nic->hw_rx_tstamp = true;
		config.rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		return -ERANGE;
	}

	if (netif_running(netdev))
		nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp);

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static int nicvf_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
{
	switch (cmd) {
	case SIOCSHWTSTAMP:
		return nicvf_config_hwtstamp(netdev, req);
	default:
		return -EOPNOTSUPP;
	}
}

static void __nicvf_set_rx_mode_task(u8 mode, struct xcast_addr_list *mc_addrs,
				     struct nicvf *nic)
{
	union nic_mbx mbx = {};
	int idx;

	/* From the inside of VM code flow we have only 128 bits memory
	 * available to send message to host's PF, so send all mc addrs
	 * one by one, starting from flush command in case if kernel
	 * requests to configure specific MAC filtering
	 */

	/* flush DMAC filters and reset RX mode */
	mbx.xcast.msg = NIC_MBOX_MSG_RESET_XCAST;
	if (nicvf_send_msg_to_pf(nic, &mbx) < 0)
		goto free_mc;

	if (mode & BGX_XCAST_MCAST_FILTER) {
		/* once enabling filtering, we need to signal to PF to add
		 * its' own LMAC to the filter to accept packets for it.
		 */
		mbx.xcast.msg = NIC_MBOX_MSG_ADD_MCAST;
		mbx.xcast.mac = 0;
		if (nicvf_send_msg_to_pf(nic, &mbx) < 0)
			goto free_mc;
	}

	/* check if we have any specific MACs to be added to PF DMAC filter */
	if (mc_addrs) {
		/* now go through kernel list of MACs and add them one by one */
		for (idx = 0; idx < mc_addrs->count; idx++) {
			mbx.xcast.msg = NIC_MBOX_MSG_ADD_MCAST;
			mbx.xcast.mac = mc_addrs->mc[idx];
			if (nicvf_send_msg_to_pf(nic, &mbx) < 0)
				goto free_mc;
		}
	}

	/* and finally set rx mode for PF accordingly */
	mbx.xcast.msg = NIC_MBOX_MSG_SET_XCAST;
	mbx.xcast.mode = mode;

	nicvf_send_msg_to_pf(nic, &mbx);
free_mc:
	kfree(mc_addrs);
}

static void nicvf_set_rx_mode_task(struct work_struct *work_arg)
{
	struct nicvf_work *vf_work = container_of(work_arg, struct nicvf_work,
						  work);
	struct nicvf *nic = container_of(vf_work, struct nicvf, rx_mode_work);
	u8 mode;
	struct xcast_addr_list *mc;

	if (!vf_work)
		return;

	/* Save message data locally to prevent them from
	 * being overwritten by next ndo_set_rx_mode call().
	 */
	spin_lock(&nic->rx_mode_wq_lock);
	mode = vf_work->mode;
	mc = vf_work->mc;
	vf_work->mc = NULL;
	spin_unlock(&nic->rx_mode_wq_lock);

	__nicvf_set_rx_mode_task(mode, mc, nic);
}

static void nicvf_set_rx_mode(struct net_device *netdev)
{
	struct nicvf *nic = netdev_priv(netdev);
	struct netdev_hw_addr *ha;
	struct xcast_addr_list *mc_list = NULL;
	u8 mode = 0;

	if (netdev->flags & IFF_PROMISC) {
		mode = BGX_XCAST_BCAST_ACCEPT | BGX_XCAST_MCAST_ACCEPT;
	} else {
		if (netdev->flags & IFF_BROADCAST)
			mode |= BGX_XCAST_BCAST_ACCEPT;

		if (netdev->flags & IFF_ALLMULTI) {
			mode |= BGX_XCAST_MCAST_ACCEPT;
		} else if (netdev->flags & IFF_MULTICAST) {
			mode |= BGX_XCAST_MCAST_FILTER;
			/* here we need to copy mc addrs */
			if (netdev_mc_count(netdev)) {
				mc_list = kmalloc(offsetof(typeof(*mc_list),
							   mc[netdev_mc_count(netdev)]),
						  GFP_ATOMIC);
				if (unlikely(!mc_list))
					return;
				mc_list->count = 0;
				netdev_hw_addr_list_for_each(ha, &netdev->mc) {
					mc_list->mc[mc_list->count] =
						ether_addr_to_u64(ha->addr);
					mc_list->count++;
				}
			}
		}
	}
	spin_lock(&nic->rx_mode_wq_lock);
	kfree(nic->rx_mode_work.mc);
	nic->rx_mode_work.mc = mc_list;
	nic->rx_mode_work.mode = mode;
	queue_work(nic->nicvf_rx_mode_wq, &nic->rx_mode_work.work);
	spin_unlock(&nic->rx_mode_wq_lock);
}

static const struct net_device_ops nicvf_netdev_ops = {
	.ndo_open		= nicvf_open,
	.ndo_stop		= nicvf_stop,
	.ndo_start_xmit		= nicvf_xmit,
	.ndo_change_mtu		= nicvf_change_mtu,
	.ndo_set_mac_address	= nicvf_set_mac_address,
	.ndo_get_stats64	= nicvf_get_stats64,
	.ndo_tx_timeout         = nicvf_tx_timeout,
	.ndo_fix_features       = nicvf_fix_features,
	.ndo_set_features       = nicvf_set_features,
	.ndo_bpf		= nicvf_xdp,
	.ndo_do_ioctl           = nicvf_ioctl,
	.ndo_set_rx_mode        = nicvf_set_rx_mode,
};

static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct device *dev = &pdev->dev;
	struct net_device *netdev;
	struct nicvf *nic;
	int    err, qcount;
	u16    sdevid;
	struct cavium_ptp *ptp_clock;

	ptp_clock = cavium_ptp_get();
	if (IS_ERR(ptp_clock)) {
		if (PTR_ERR(ptp_clock) == -ENODEV)
			/* In virtualized environment we proceed without ptp */
			ptp_clock = NULL;
		else
			return PTR_ERR(ptp_clock);
	}

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(dev, "Failed to enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRV_NAME);
	if (err) {
		dev_err(dev, "PCI request regions failed 0x%x\n", err);
		goto err_disable_device;
	}

	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(48));
	if (err) {
		dev_err(dev, "Unable to get usable DMA configuration\n");
		goto err_release_regions;
	}

	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(48));
	if (err) {
		dev_err(dev, "unable to get 48-bit DMA for consistent allocations\n");
		goto err_release_regions;
	}

	qcount = netif_get_num_default_rss_queues();

	/* Restrict multiqset support only for host bound VFs */
	if (pdev->is_virtfn) {
		/* Set max number of queues per VF */
		qcount = min_t(int, num_online_cpus(),
			       (MAX_SQS_PER_VF + 1) * MAX_CMP_QUEUES_PER_QS);
	}

	netdev = alloc_etherdev_mqs(sizeof(struct nicvf), qcount, qcount);
	if (!netdev) {
		err = -ENOMEM;
		goto err_release_regions;
	}

	pci_set_drvdata(pdev, netdev);

	SET_NETDEV_DEV(netdev, &pdev->dev);

	nic = netdev_priv(netdev);
	nic->netdev = netdev;
	nic->pdev = pdev;
	nic->pnicvf = nic;
	nic->max_queues = qcount;
	/* If no of CPUs are too low, there won't be any queues left
	 * for XDP_TX, hence double it.
	 */
	if (!nic->t88)
		nic->max_queues *= 2;
	nic->ptp_clock = ptp_clock;

	/* MAP VF's configuration registers */
	nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
	if (!nic->reg_base) {
		dev_err(dev, "Cannot map config register space, aborting\n");
		err = -ENOMEM;
		goto err_free_netdev;
	}

	nic->drv_stats = netdev_alloc_pcpu_stats(struct nicvf_drv_stats);
	if (!nic->drv_stats) {
		err = -ENOMEM;
		goto err_free_netdev;
	}

	err = nicvf_set_qset_resources(nic);
	if (err)
		goto err_free_netdev;

	/* Check if PF is alive and get MAC address for this VF */
	err = nicvf_register_misc_interrupt(nic);
	if (err)
		goto err_free_netdev;

	nicvf_send_vf_struct(nic);

	if (!pass1_silicon(nic->pdev))
		nic->hw_tso = true;

	/* Get iommu domain for iova to physical addr conversion */
	nic->iommu_domain = iommu_get_domain_for_dev(dev);

	pci_read_config_word(nic->pdev, PCI_SUBSYSTEM_ID, &sdevid);
	if (sdevid == 0xA134)
		nic->t88 = true;

	/* Check if this VF is in QS only mode */
	if (nic->sqs_mode)
		return 0;

	err = nicvf_set_real_num_queues(netdev, nic->tx_queues, nic->rx_queues);
	if (err)
		goto err_unregister_interrupts;

	netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_SG |
			       NETIF_F_TSO | NETIF_F_GRO | NETIF_F_TSO6 |
			       NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
			       NETIF_F_HW_VLAN_CTAG_RX);

	netdev->hw_features |= NETIF_F_RXHASH;

	netdev->features |= netdev->hw_features;
	netdev->hw_features |= NETIF_F_LOOPBACK;

	netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM |
				NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6;

	netdev->netdev_ops = &nicvf_netdev_ops;
	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;

	/* MTU range: 64 - 9200 */
	netdev->min_mtu = NIC_HW_MIN_FRS;
	netdev->max_mtu = NIC_HW_MAX_FRS;

	INIT_WORK(&nic->reset_task, nicvf_reset_task);

	nic->nicvf_rx_mode_wq = alloc_ordered_workqueue("nicvf_rx_mode_wq_VF%d",
							WQ_MEM_RECLAIM,
							nic->vf_id);
	if (!nic->nicvf_rx_mode_wq) {
		err = -ENOMEM;
		dev_err(dev, "Failed to allocate work queue\n");
		goto err_unregister_interrupts;
	}

	INIT_WORK(&nic->rx_mode_work.work, nicvf_set_rx_mode_task);
	spin_lock_init(&nic->rx_mode_wq_lock);
	mutex_init(&nic->rx_mode_mtx);

	err = register_netdev(netdev);
	if (err) {
		dev_err(dev, "Failed to register netdevice\n");
		goto err_unregister_interrupts;
	}

	nic->msg_enable = debug;

	nicvf_set_ethtool_ops(netdev);

	return 0;

err_unregister_interrupts:
	nicvf_unregister_interrupts(nic);
err_free_netdev:
	pci_set_drvdata(pdev, NULL);
	if (nic->drv_stats)
		free_percpu(nic->drv_stats);
	free_netdev(netdev);
err_release_regions:
	pci_release_regions(pdev);
err_disable_device:
	pci_disable_device(pdev);
	return err;
}

static void nicvf_remove(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct nicvf *nic;
	struct net_device *pnetdev;

	if (!netdev)
		return;

	nic = netdev_priv(netdev);
	pnetdev = nic->pnicvf->netdev;

	/* Check if this Qset is assigned to different VF.
	 * If yes, clean primary and all secondary Qsets.
	 */
	if (pnetdev && (pnetdev->reg_state == NETREG_REGISTERED))
		unregister_netdev(pnetdev);
	if (nic->nicvf_rx_mode_wq) {
		destroy_workqueue(nic->nicvf_rx_mode_wq);
		nic->nicvf_rx_mode_wq = NULL;
	}
	nicvf_unregister_interrupts(nic);
	pci_set_drvdata(pdev, NULL);
	if (nic->drv_stats)
		free_percpu(nic->drv_stats);
	cavium_ptp_put(nic->ptp_clock);
	free_netdev(netdev);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
}

static void nicvf_shutdown(struct pci_dev *pdev)
{
	nicvf_remove(pdev);
}

static struct pci_driver nicvf_driver = {
	.name = DRV_NAME,
	.id_table = nicvf_id_table,
	.probe = nicvf_probe,
	.remove = nicvf_remove,
	.shutdown = nicvf_shutdown,
};

static int __init nicvf_init_module(void)
{
	pr_info("%s, ver %s\n", DRV_NAME, DRV_VERSION);
	return pci_register_driver(&nicvf_driver);
}

static void __exit nicvf_cleanup_module(void)
{
	pci_unregister_driver(&nicvf_driver);
}

module_init(nicvf_init_module);
module_exit(nicvf_cleanup_module);
