// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Admin Function driver
 *
 * Copyright (C) 2018 Marvell.
 *
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>

#include "rvu.h"
#include "cgx.h"
#include "lmac_common.h"
#include "rvu_reg.h"
#include "rvu_trace.h"

struct cgx_evq_entry {
	struct list_head evq_node;
	struct cgx_link_event link_event;
};

#define M(_name, _id, _fn_name, _req_type, _rsp_type)			\
static struct _req_type __maybe_unused					\
*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid)		\
{									\
	struct _req_type *req;						\
									\
	req = (struct _req_type *)otx2_mbox_alloc_msg_rsp(		\
		&rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \
		sizeof(struct _rsp_type));				\
	if (!req)							\
		return NULL;						\
	req->hdr.sig = OTX2_MBOX_REQ_SIG;				\
	req->hdr.id = _id;						\
	trace_otx2_msg_alloc(rvu->pdev, _id, sizeof(*req));		\
	return req;							\
}

MBOX_UP_CGX_MESSAGES
#undef M

bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature)
{
	u8 cgx_id, lmac_id;
	void *cgxd;

	if (!is_pf_cgxmapped(rvu, pf))
		return 0;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	cgxd = rvu_cgx_pdata(cgx_id, rvu);

	return  (cgx_features_get(cgxd) & feature);
}

/* Returns bitmap of mapped PFs */
static u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id)
{
	return rvu->cgxlmac2pf_map[CGX_OFFSET(cgx_id) + lmac_id];
}

int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id)
{
	unsigned long pfmap;

	pfmap = cgxlmac_to_pfmap(rvu, cgx_id, lmac_id);

	/* Assumes only one pf mapped to a cgx lmac port */
	if (!pfmap)
		return -ENODEV;
	else
		return find_first_bit(&pfmap, 16);
}

static u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id)
{
	return ((cgx_id & 0xF) << 4) | (lmac_id & 0xF);
}

void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu)
{
	if (cgx_id >= rvu->cgx_cnt_max)
		return NULL;

	return rvu->cgx_idmap[cgx_id];
}

/* Return first enabled CGX instance if none are enabled then return NULL */
void *rvu_first_cgx_pdata(struct rvu *rvu)
{
	int first_enabled_cgx = 0;
	void *cgxd = NULL;

	for (; first_enabled_cgx < rvu->cgx_cnt_max; first_enabled_cgx++) {
		cgxd = rvu_cgx_pdata(first_enabled_cgx, rvu);
		if (cgxd)
			break;
	}

	return cgxd;
}

/* Based on P2X connectivity find mapped NIX block for a PF */
static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
				  int cgx_id, int lmac_id)
{
	struct rvu_pfvf *pfvf = &rvu->pf[pf];
	u8 p2x;

	p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
	/* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
	pfvf->nix_blkaddr = BLKADDR_NIX0;
	if (p2x == CMR_P2X_SEL_NIX1)
		pfvf->nix_blkaddr = BLKADDR_NIX1;
}

static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
{
	struct npc_pkind *pkind = &rvu->hw->pkind;
	int cgx_cnt_max = rvu->cgx_cnt_max;
	int pf = PF_CGXMAP_BASE;
	unsigned long lmac_bmap;
	int size, free_pkind;
	int cgx, lmac, iter;
	int numvfs, hwvfs;

	if (!cgx_cnt_max)
		return 0;

	if (cgx_cnt_max > 0xF || MAX_LMAC_PER_CGX > 0xF)
		return -EINVAL;

	/* Alloc map table
	 * An additional entry is required since PF id starts from 1 and
	 * hence entry at offset 0 is invalid.
	 */
	size = (cgx_cnt_max * MAX_LMAC_PER_CGX + 1) * sizeof(u8);
	rvu->pf2cgxlmac_map = devm_kmalloc(rvu->dev, size, GFP_KERNEL);
	if (!rvu->pf2cgxlmac_map)
		return -ENOMEM;

	/* Initialize all entries with an invalid cgx and lmac id */
	memset(rvu->pf2cgxlmac_map, 0xFF, size);

	/* Reverse map table */
	rvu->cgxlmac2pf_map = devm_kzalloc(rvu->dev,
				  cgx_cnt_max * MAX_LMAC_PER_CGX * sizeof(u16),
				  GFP_KERNEL);
	if (!rvu->cgxlmac2pf_map)
		return -ENOMEM;

	rvu->cgx_mapped_pfs = 0;
	for (cgx = 0; cgx < cgx_cnt_max; cgx++) {
		if (!rvu_cgx_pdata(cgx, rvu))
			continue;
		lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
		for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) {
			lmac = cgx_get_lmacid(rvu_cgx_pdata(cgx, rvu),
					      iter);
			rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac);
			rvu->cgxlmac2pf_map[CGX_OFFSET(cgx) + lmac] = 1 << pf;
			free_pkind = rvu_alloc_rsrc(&pkind->rsrc);
			pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16;
			rvu_map_cgx_nix_block(rvu, pf, cgx, lmac);
			rvu->cgx_mapped_pfs++;
			rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvfs);
			rvu->cgx_mapped_vfs += numvfs;
			pf++;
		}
	}
	return 0;
}

static int rvu_cgx_send_link_info(int cgx_id, int lmac_id, struct rvu *rvu)
{
	struct cgx_evq_entry *qentry;
	unsigned long flags;
	int err;

	qentry = kmalloc(sizeof(*qentry), GFP_KERNEL);
	if (!qentry)
		return -ENOMEM;

	/* Lock the event queue before we read the local link status */
	spin_lock_irqsave(&rvu->cgx_evq_lock, flags);
	err = cgx_get_link_info(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
				&qentry->link_event.link_uinfo);
	qentry->link_event.cgx_id = cgx_id;
	qentry->link_event.lmac_id = lmac_id;
	if (err) {
		kfree(qentry);
		goto skip_add;
	}
	list_add_tail(&qentry->evq_node, &rvu->cgx_evq_head);
skip_add:
	spin_unlock_irqrestore(&rvu->cgx_evq_lock, flags);

	/* start worker to process the events */
	queue_work(rvu->cgx_evh_wq, &rvu->cgx_evh_work);

	return 0;
}

/* This is called from interrupt context and is expected to be atomic */
static int cgx_lmac_postevent(struct cgx_link_event *event, void *data)
{
	struct cgx_evq_entry *qentry;
	struct rvu *rvu = data;

	/* post event to the event queue */
	qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC);
	if (!qentry)
		return -ENOMEM;
	qentry->link_event = *event;
	spin_lock(&rvu->cgx_evq_lock);
	list_add_tail(&qentry->evq_node, &rvu->cgx_evq_head);
	spin_unlock(&rvu->cgx_evq_lock);

	/* start worker to process the events */
	queue_work(rvu->cgx_evh_wq, &rvu->cgx_evh_work);

	return 0;
}

static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
{
	struct cgx_link_user_info *linfo;
	struct cgx_link_info_msg *msg;
	unsigned long pfmap;
	int err, pfid;

	linfo = &event->link_uinfo;
	pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id);

	do {
		pfid = find_first_bit(&pfmap, 16);
		clear_bit(pfid, &pfmap);

		/* check if notification is enabled */
		if (!test_bit(pfid, &rvu->pf_notify_bmap)) {
			dev_info(rvu->dev, "cgx %d: lmac %d Link status %s\n",
				 event->cgx_id, event->lmac_id,
				 linfo->link_up ? "UP" : "DOWN");
			continue;
		}

		/* Send mbox message to PF */
		msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid);
		if (!msg)
			continue;
		msg->link_info = *linfo;
		otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid);
		err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
		if (err)
			dev_warn(rvu->dev, "notification to pf %d failed\n",
				 pfid);
	} while (pfmap);
}

static void cgx_evhandler_task(struct work_struct *work)
{
	struct rvu *rvu = container_of(work, struct rvu, cgx_evh_work);
	struct cgx_evq_entry *qentry;
	struct cgx_link_event *event;
	unsigned long flags;

	do {
		/* Dequeue an event */
		spin_lock_irqsave(&rvu->cgx_evq_lock, flags);
		qentry = list_first_entry_or_null(&rvu->cgx_evq_head,
						  struct cgx_evq_entry,
						  evq_node);
		if (qentry)
			list_del(&qentry->evq_node);
		spin_unlock_irqrestore(&rvu->cgx_evq_lock, flags);
		if (!qentry)
			break; /* nothing more to process */

		event = &qentry->link_event;

		/* process event */
		cgx_notify_pfs(event, rvu);
		kfree(qentry);
	} while (1);
}

static int cgx_lmac_event_handler_init(struct rvu *rvu)
{
	unsigned long lmac_bmap;
	struct cgx_event_cb cb;
	int cgx, lmac, err;
	void *cgxd;

	spin_lock_init(&rvu->cgx_evq_lock);
	INIT_LIST_HEAD(&rvu->cgx_evq_head);
	INIT_WORK(&rvu->cgx_evh_work, cgx_evhandler_task);
	rvu->cgx_evh_wq = alloc_workqueue("rvu_evh_wq", 0, 0);
	if (!rvu->cgx_evh_wq) {
		dev_err(rvu->dev, "alloc workqueue failed");
		return -ENOMEM;
	}

	cb.notify_link_chg = cgx_lmac_postevent; /* link change call back */
	cb.data = rvu;

	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
		cgxd = rvu_cgx_pdata(cgx, rvu);
		if (!cgxd)
			continue;
		lmac_bmap = cgx_get_lmac_bmap(cgxd);
		for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX) {
			err = cgx_lmac_evh_register(&cb, cgxd, lmac);
			if (err)
				dev_err(rvu->dev,
					"%d:%d handler register failed\n",
					cgx, lmac);
		}
	}

	return 0;
}

static void rvu_cgx_wq_destroy(struct rvu *rvu)
{
	if (rvu->cgx_evh_wq) {
		destroy_workqueue(rvu->cgx_evh_wq);
		rvu->cgx_evh_wq = NULL;
	}
}

int rvu_cgx_init(struct rvu *rvu)
{
	int cgx, err;
	void *cgxd;

	/* CGX port id starts from 0 and are not necessarily contiguous
	 * Hence we allocate resources based on the maximum port id value.
	 */
	rvu->cgx_cnt_max = cgx_get_cgxcnt_max();
	if (!rvu->cgx_cnt_max) {
		dev_info(rvu->dev, "No CGX devices found!\n");
		return -ENODEV;
	}

	rvu->cgx_idmap = devm_kzalloc(rvu->dev, rvu->cgx_cnt_max *
				      sizeof(void *), GFP_KERNEL);
	if (!rvu->cgx_idmap)
		return -ENOMEM;

	/* Initialize the cgxdata table */
	for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++)
		rvu->cgx_idmap[cgx] = cgx_get_pdata(cgx);

	/* Map CGX LMAC interfaces to RVU PFs */
	err = rvu_map_cgx_lmac_pf(rvu);
	if (err)
		return err;

	/* Register for CGX events */
	err = cgx_lmac_event_handler_init(rvu);
	if (err)
		return err;

	mutex_init(&rvu->cgx_cfg_lock);

	/* Ensure event handler registration is completed, before
	 * we turn on the links
	 */
	mb();

	/* Do link up for all CGX ports */
	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
		cgxd = rvu_cgx_pdata(cgx, rvu);
		if (!cgxd)
			continue;
		err = cgx_lmac_linkup_start(cgxd);
		if (err)
			dev_err(rvu->dev,
				"Link up process failed to start on cgx %d\n",
				cgx);
	}

	return 0;
}

int rvu_cgx_exit(struct rvu *rvu)
{
	unsigned long lmac_bmap;
	int cgx, lmac;
	void *cgxd;

	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
		cgxd = rvu_cgx_pdata(cgx, rvu);
		if (!cgxd)
			continue;
		lmac_bmap = cgx_get_lmac_bmap(cgxd);
		for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX)
			cgx_lmac_evh_unregister(cgxd, lmac);
	}

	/* Ensure event handler unregister is completed */
	mb();

	rvu_cgx_wq_destroy(rvu);
	return 0;
}

/* Most of the CGX configuration is restricted to the mapped PF only,
 * VF's of mapped PF and other PFs are not allowed. This fn() checks
 * whether a PFFUNC is permitted to do the config or not.
 */
inline bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
{
	if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
	    !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
		return false;
	return true;
}

void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable)
{
	struct mac_ops *mac_ops;
	u8 cgx_id, lmac_id;
	void *cgxd;

	if (!is_pf_cgxmapped(rvu, pf))
		return;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	cgxd = rvu_cgx_pdata(cgx_id, rvu);

	mac_ops = get_mac_ops(cgxd);
	/* Set / clear CTL_BCK to control pause frame forwarding to NIX */
	if (enable)
		mac_ops->mac_enadis_rx_pause_fwding(cgxd, lmac_id, true);
	else
		mac_ops->mac_enadis_rx_pause_fwding(cgxd, lmac_id, false);
}

int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
{
	int pf = rvu_get_pf(pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	cgx_lmac_rx_tx_enable(rvu_cgx_pdata(cgx_id, rvu), lmac_id, start);

	return 0;
}

void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
{
	int pf = rvu_get_pf(pcifunc);
	int i = 0, lmac_count = 0;
	u8 max_dmac_filters;
	u8 cgx_id, lmac_id;
	void *cgx_dev;

	if (!is_cgx_config_permitted(rvu, pcifunc))
		return;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	cgx_dev = cgx_get_pdata(cgx_id);
	lmac_count = cgx_get_lmac_cnt(cgx_dev);
	max_dmac_filters = MAX_DMAC_ENTRIES_PER_CGX / lmac_count;

	for (i = 0; i < max_dmac_filters; i++)
		cgx_lmac_addr_del(cgx_id, lmac_id, i);

	/* As cgx_lmac_addr_del does not clear entry for index 0
	 * so it needs to be done explicitly
	 */
	cgx_lmac_addr_reset(cgx_id, lmac_id);
}

int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
				    struct msg_rsp *rsp)
{
	rvu_cgx_config_rxtx(rvu, req->hdr.pcifunc, true);
	return 0;
}

int rvu_mbox_handler_cgx_stop_rxtx(struct rvu *rvu, struct msg_req *req,
				   struct msg_rsp *rsp)
{
	rvu_cgx_config_rxtx(rvu, req->hdr.pcifunc, false);
	return 0;
}

static int rvu_lmac_get_stats(struct rvu *rvu, struct msg_req *req,
			      void *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	struct mac_ops *mac_ops;
	int stat = 0, err = 0;
	u64 tx_stat, rx_stat;
	u8 cgx_idx, lmac;
	void *cgxd;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
	mac_ops = get_mac_ops(cgxd);

	/* Rx stats */
	while (stat < mac_ops->rx_stats_cnt) {
		err = mac_ops->mac_get_rx_stats(cgxd, lmac, stat, &rx_stat);
		if (err)
			return err;
		if (mac_ops->rx_stats_cnt == RPM_RX_STATS_COUNT)
			((struct rpm_stats_rsp *)rsp)->rx_stats[stat] = rx_stat;
		else
			((struct cgx_stats_rsp *)rsp)->rx_stats[stat] = rx_stat;
		stat++;
	}

	/* Tx stats */
	stat = 0;
	while (stat < mac_ops->tx_stats_cnt) {
		err = mac_ops->mac_get_tx_stats(cgxd, lmac, stat, &tx_stat);
		if (err)
			return err;
		if (mac_ops->tx_stats_cnt == RPM_TX_STATS_COUNT)
			((struct rpm_stats_rsp *)rsp)->tx_stats[stat] = tx_stat;
		else
			((struct cgx_stats_rsp *)rsp)->tx_stats[stat] = tx_stat;
		stat++;
	}
	return 0;
}

int rvu_mbox_handler_cgx_stats(struct rvu *rvu, struct msg_req *req,
			       struct cgx_stats_rsp *rsp)
{
	return rvu_lmac_get_stats(rvu, req, (void *)rsp);
}

int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
			       struct rpm_stats_rsp *rsp)
{
	return rvu_lmac_get_stats(rvu, req, (void *)rsp);
}

int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
				   struct msg_req *req,
				   struct cgx_fec_stats_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_idx, lmac;
	void *cgxd;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;
	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);

	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
	return cgx_get_fec_stats(cgxd, lmac, rsp);
}

int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
				      struct cgx_mac_addr_set_or_get *req,
				      struct cgx_mac_addr_set_or_get *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);

	return 0;
}

int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
				      struct cgx_mac_addr_add_req *req,
				      struct cgx_mac_addr_add_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;
	int rc = 0;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	rc = cgx_lmac_addr_add(cgx_id, lmac_id, req->mac_addr);
	if (rc >= 0) {
		rsp->index = rc;
		return 0;
	}

	return rc;
}

int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
				      struct cgx_mac_addr_del_req *req,
				      struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	return cgx_lmac_addr_del(cgx_id, lmac_id, req->index);
}

int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
					     struct msg_req *req,
					     struct cgx_max_dmac_entries_get_rsp
					     *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	/* If msg is received from PFs(which are not mapped to CGX LMACs)
	 * or VF then no entries are allocated for DMAC filters at CGX level.
	 * So returning zero.
	 */
	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) {
		rsp->max_dmac_filters = 0;
		return 0;
	}

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	rsp->max_dmac_filters = cgx_lmac_addr_max_entries_get(cgx_id, lmac_id);
	return 0;
}

int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
				      struct cgx_mac_addr_set_or_get *req,
				      struct cgx_mac_addr_set_or_get *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;
	int rc = 0, i;
	u64 cfg;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	rsp->hdr.rc = rc;
	cfg = cgx_lmac_addr_get(cgx_id, lmac_id);
	/* copy 48 bit mac address to req->mac_addr */
	for (i = 0; i < ETH_ALEN; i++)
		rsp->mac_addr[i] = cfg >> (ETH_ALEN - 1 - i) * 8;
	return 0;
}

int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
					struct msg_rsp *rsp)
{
	u16 pcifunc = req->hdr.pcifunc;
	int pf = rvu_get_pf(pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	cgx_lmac_promisc_config(cgx_id, lmac_id, true);
	return 0;
}

int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
					 struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	cgx_lmac_promisc_config(cgx_id, lmac_id, false);
	return 0;
}

static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	int pf = rvu_get_pf(pcifunc);
	struct mac_ops *mac_ops;
	u8 cgx_id, lmac_id;
	void *cgxd;

	if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
		return 0;

	/* This msg is expected only from PFs that are mapped to CGX LMACs,
	 * if received from other PF/VF simply ACK, nothing to do.
	 */
	if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
	    !is_pf_cgxmapped(rvu, pf))
		return -ENODEV;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	cgxd = rvu_cgx_pdata(cgx_id, rvu);

	mac_ops = get_mac_ops(cgxd);
	mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, true);
	/* If PTP is enabled then inform NPC that packets to be
	 * parsed by this PF will have their data shifted by 8 bytes
	 * and if PTP is disabled then no shift is required
	 */
	if (npc_config_ts_kpuaction(rvu, pf, pcifunc, enable))
		return -EINVAL;
	/* This flag is required to clean up CGX conf if app gets killed */
	pfvf->hw_rx_tstamp_en = enable;

	return 0;
}

int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
				       struct msg_rsp *rsp)
{
	if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
		return -EPERM;

	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
}

int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
					struct msg_rsp *rsp)
{
	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, false);
}

static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
{
	int pf = rvu_get_pf(pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	if (en) {
		set_bit(pf, &rvu->pf_notify_bmap);
		/* Send the current link status to PF */
		rvu_cgx_send_link_info(cgx_id, lmac_id, rvu);
	} else {
		clear_bit(pf, &rvu->pf_notify_bmap);
	}

	return 0;
}

int rvu_mbox_handler_cgx_start_linkevents(struct rvu *rvu, struct msg_req *req,
					  struct msg_rsp *rsp)
{
	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, true);
	return 0;
}

int rvu_mbox_handler_cgx_stop_linkevents(struct rvu *rvu, struct msg_req *req,
					 struct msg_rsp *rsp)
{
	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, false);
	return 0;
}

int rvu_mbox_handler_cgx_get_linkinfo(struct rvu *rvu, struct msg_req *req,
				      struct cgx_link_info_msg *rsp)
{
	u8 cgx_id, lmac_id;
	int pf, err;

	pf = rvu_get_pf(req->hdr.pcifunc);

	if (!is_pf_cgxmapped(rvu, pf))
		return -ENODEV;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	err = cgx_get_link_info(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
				&rsp->link_info);
	return err;
}

int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
				      struct msg_req *req,
				      struct cgx_features_info_msg *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_idx, lmac;
	void *cgxd;

	if (!is_pf_cgxmapped(rvu, pf))
		return 0;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
	rsp->lmac_features = cgx_features_get(cgxd);

	return 0;
}

u32 rvu_cgx_get_fifolen(struct rvu *rvu)
{
	struct mac_ops *mac_ops;
	u32 fifo_len;

	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
	fifo_len = mac_ops ? mac_ops->fifo_len : 0;

	return fifo_len;
}

static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
{
	int pf = rvu_get_pf(pcifunc);
	struct mac_ops *mac_ops;
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	mac_ops = get_mac_ops(rvu_cgx_pdata(cgx_id, rvu));

	return mac_ops->mac_lmac_intl_lbk(rvu_cgx_pdata(cgx_id, rvu),
					  lmac_id, en);
}

int rvu_mbox_handler_cgx_intlbk_enable(struct rvu *rvu, struct msg_req *req,
				       struct msg_rsp *rsp)
{
	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, true);
	return 0;
}

int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
					struct msg_rsp *rsp)
{
	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, false);
	return 0;
}

int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
				       struct cgx_pause_frm_cfg *req,
				       struct cgx_pause_frm_cfg *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	struct mac_ops *mac_ops;
	u8 cgx_id, lmac_id;
	void *cgxd;

	if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_FC))
		return 0;

	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
	 * if received from other PF/VF simply ACK, nothing to do.
	 */
	if (!is_pf_cgxmapped(rvu, pf))
		return -ENODEV;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	cgxd = rvu_cgx_pdata(cgx_id, rvu);
	mac_ops = get_mac_ops(cgxd);

	if (req->set)
		mac_ops->mac_enadis_pause_frm(cgxd, lmac_id,
					      req->tx_pause, req->rx_pause);
	else
		mac_ops->mac_get_pause_frm_status(cgxd, lmac_id,
						  &rsp->tx_pause,
						  &rsp->rx_pause);
	return 0;
}

int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
					   struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_pf_cgxmapped(rvu, pf))
		return LMAC_AF_ERR_PF_NOT_MAPPED;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	return cgx_get_phy_fec_stats(rvu_cgx_pdata(cgx_id, rvu), lmac_id);
}

/* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
 * from its VFs as well. ie. NIX rx/tx counters at the CGX port level
 */
int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
			   int index, int rxtxflag, u64 *stat)
{
	struct rvu_block *block;
	int blkaddr;
	u16 pcifunc;
	int pf, lf;

	*stat = 0;

	if (!cgxd || !rvu)
		return -EINVAL;

	pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
	if (pf < 0)
		return pf;

	/* Assumes LF of a PF and all of its VF belongs to the same
	 * NIX block
	 */
	pcifunc = pf << RVU_PFVF_PF_SHIFT;
	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
	if (blkaddr < 0)
		return 0;
	block = &rvu->hw->block[blkaddr];

	for (lf = 0; lf < block->lf.max; lf++) {
		/* Check if a lf is attached to this PF or one of its VFs */
		if (!((block->fn_map[lf] & ~RVU_PFVF_FUNC_MASK) == (pcifunc &
			 ~RVU_PFVF_FUNC_MASK)))
			continue;
		if (rxtxflag == NIX_STATS_RX)
			*stat += rvu_read64(rvu, blkaddr,
					    NIX_AF_LFX_RX_STATX(lf, index));
		else
			*stat += rvu_read64(rvu, blkaddr,
					    NIX_AF_LFX_TX_STATX(lf, index));
	}

	return 0;
}

int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
{
	struct rvu_pfvf *parent_pf, *pfvf;
	int cgx_users, err = 0;

	if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
		return 0;

	parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
	pfvf = rvu_get_pfvf(rvu, pcifunc);

	mutex_lock(&rvu->cgx_cfg_lock);

	if (start && pfvf->cgx_in_use)
		goto exit;  /* CGX is already started hence nothing to do */
	if (!start && !pfvf->cgx_in_use)
		goto exit; /* CGX is already stopped hence nothing to do */

	if (start) {
		cgx_users = parent_pf->cgx_users;
		parent_pf->cgx_users++;
	} else {
		parent_pf->cgx_users--;
		cgx_users = parent_pf->cgx_users;
	}

	/* Start CGX when first of all NIXLFs is started.
	 * Stop CGX when last of all NIXLFs is stopped.
	 */
	if (!cgx_users) {
		err = rvu_cgx_config_rxtx(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK,
					  start);
		if (err) {
			dev_err(rvu->dev, "Unable to %s CGX\n",
				start ? "start" : "stop");
			/* Revert the usage count in case of error */
			parent_pf->cgx_users = start ? parent_pf->cgx_users  - 1
					       : parent_pf->cgx_users  + 1;
			goto exit;
		}
	}
	pfvf->cgx_in_use = start;
exit:
	mutex_unlock(&rvu->cgx_cfg_lock);
	return err;
}

int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
				       struct fec_mode *req,
				       struct fec_mode *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_pf_cgxmapped(rvu, pf))
		return -EPERM;

	if (req->fec == OTX2_FEC_OFF)
		req->fec = OTX2_FEC_NONE;
	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
	return 0;
}

int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
					   struct cgx_fw_data *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!rvu->fwdata)
		return -ENXIO;

	if (!is_pf_cgxmapped(rvu, pf))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	memcpy(&rsp->fwdata, &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id],
	       sizeof(struct cgx_lmac_fwdata_s));
	return 0;
}

int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
				       struct cgx_set_link_mode_req *req,
				       struct cgx_set_link_mode_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_idx, lmac;
	void *cgxd;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
	rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac);
	return 0;
}

int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct msg_req *req,
					struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	return cgx_lmac_addr_reset(cgx_id, lmac_id);
}

int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
					 struct cgx_mac_addr_update_req *req,
					 struct msg_rsp *rsp)
{
	int pf = rvu_get_pf(req->hdr.pcifunc);
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return LMAC_AF_ERR_PERM_DENIED;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
}
