cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rvu_cgx.c (30487B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Marvell RVU Admin Function driver
      3 *
      4 * Copyright (C) 2018 Marvell.
      5 *
      6 */
      7
      8#include <linux/types.h>
      9#include <linux/module.h>
     10#include <linux/pci.h>
     11
     12#include "rvu.h"
     13#include "cgx.h"
     14#include "lmac_common.h"
     15#include "rvu_reg.h"
     16#include "rvu_trace.h"
     17
     18struct cgx_evq_entry {
     19	struct list_head evq_node;
     20	struct cgx_link_event link_event;
     21};
     22
     23#define M(_name, _id, _fn_name, _req_type, _rsp_type)			\
     24static struct _req_type __maybe_unused					\
     25*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid)		\
     26{									\
     27	struct _req_type *req;						\
     28									\
     29	req = (struct _req_type *)otx2_mbox_alloc_msg_rsp(		\
     30		&rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \
     31		sizeof(struct _rsp_type));				\
     32	if (!req)							\
     33		return NULL;						\
     34	req->hdr.sig = OTX2_MBOX_REQ_SIG;				\
     35	req->hdr.id = _id;						\
     36	trace_otx2_msg_alloc(rvu->pdev, _id, sizeof(*req));		\
     37	return req;							\
     38}
     39
     40MBOX_UP_CGX_MESSAGES
     41#undef M
     42
     43bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature)
     44{
     45	u8 cgx_id, lmac_id;
     46	void *cgxd;
     47
     48	if (!is_pf_cgxmapped(rvu, pf))
     49		return 0;
     50
     51	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
     52	cgxd = rvu_cgx_pdata(cgx_id, rvu);
     53
     54	return  (cgx_features_get(cgxd) & feature);
     55}
     56
     57/* Returns bitmap of mapped PFs */
     58static u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id)
     59{
     60	return rvu->cgxlmac2pf_map[CGX_OFFSET(cgx_id) + lmac_id];
     61}
     62
     63int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id)
     64{
     65	unsigned long pfmap;
     66
     67	pfmap = cgxlmac_to_pfmap(rvu, cgx_id, lmac_id);
     68
     69	/* Assumes only one pf mapped to a cgx lmac port */
     70	if (!pfmap)
     71		return -ENODEV;
     72	else
     73		return find_first_bit(&pfmap, 16);
     74}
     75
     76static u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id)
     77{
     78	return ((cgx_id & 0xF) << 4) | (lmac_id & 0xF);
     79}
     80
     81void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu)
     82{
     83	if (cgx_id >= rvu->cgx_cnt_max)
     84		return NULL;
     85
     86	return rvu->cgx_idmap[cgx_id];
     87}
     88
     89/* Return first enabled CGX instance if none are enabled then return NULL */
     90void *rvu_first_cgx_pdata(struct rvu *rvu)
     91{
     92	int first_enabled_cgx = 0;
     93	void *cgxd = NULL;
     94
     95	for (; first_enabled_cgx < rvu->cgx_cnt_max; first_enabled_cgx++) {
     96		cgxd = rvu_cgx_pdata(first_enabled_cgx, rvu);
     97		if (cgxd)
     98			break;
     99	}
    100
    101	return cgxd;
    102}
    103
    104/* Based on P2X connectivity find mapped NIX block for a PF */
    105static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
    106				  int cgx_id, int lmac_id)
    107{
    108	struct rvu_pfvf *pfvf = &rvu->pf[pf];
    109	u8 p2x;
    110
    111	p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
    112	/* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
    113	pfvf->nix_blkaddr = BLKADDR_NIX0;
    114	if (p2x == CMR_P2X_SEL_NIX1)
    115		pfvf->nix_blkaddr = BLKADDR_NIX1;
    116}
    117
    118static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
    119{
    120	struct npc_pkind *pkind = &rvu->hw->pkind;
    121	int cgx_cnt_max = rvu->cgx_cnt_max;
    122	int pf = PF_CGXMAP_BASE;
    123	unsigned long lmac_bmap;
    124	int size, free_pkind;
    125	int cgx, lmac, iter;
    126	int numvfs, hwvfs;
    127
    128	if (!cgx_cnt_max)
    129		return 0;
    130
    131	if (cgx_cnt_max > 0xF || MAX_LMAC_PER_CGX > 0xF)
    132		return -EINVAL;
    133
    134	/* Alloc map table
    135	 * An additional entry is required since PF id starts from 1 and
    136	 * hence entry at offset 0 is invalid.
    137	 */
    138	size = (cgx_cnt_max * MAX_LMAC_PER_CGX + 1) * sizeof(u8);
    139	rvu->pf2cgxlmac_map = devm_kmalloc(rvu->dev, size, GFP_KERNEL);
    140	if (!rvu->pf2cgxlmac_map)
    141		return -ENOMEM;
    142
    143	/* Initialize all entries with an invalid cgx and lmac id */
    144	memset(rvu->pf2cgxlmac_map, 0xFF, size);
    145
    146	/* Reverse map table */
    147	rvu->cgxlmac2pf_map = devm_kzalloc(rvu->dev,
    148				  cgx_cnt_max * MAX_LMAC_PER_CGX * sizeof(u16),
    149				  GFP_KERNEL);
    150	if (!rvu->cgxlmac2pf_map)
    151		return -ENOMEM;
    152
    153	rvu->cgx_mapped_pfs = 0;
    154	for (cgx = 0; cgx < cgx_cnt_max; cgx++) {
    155		if (!rvu_cgx_pdata(cgx, rvu))
    156			continue;
    157		lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
    158		for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) {
    159			lmac = cgx_get_lmacid(rvu_cgx_pdata(cgx, rvu),
    160					      iter);
    161			rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac);
    162			rvu->cgxlmac2pf_map[CGX_OFFSET(cgx) + lmac] = 1 << pf;
    163			free_pkind = rvu_alloc_rsrc(&pkind->rsrc);
    164			pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16;
    165			rvu_map_cgx_nix_block(rvu, pf, cgx, lmac);
    166			rvu->cgx_mapped_pfs++;
    167			rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvfs);
    168			rvu->cgx_mapped_vfs += numvfs;
    169			pf++;
    170		}
    171	}
    172	return 0;
    173}
    174
    175static int rvu_cgx_send_link_info(int cgx_id, int lmac_id, struct rvu *rvu)
    176{
    177	struct cgx_evq_entry *qentry;
    178	unsigned long flags;
    179	int err;
    180
    181	qentry = kmalloc(sizeof(*qentry), GFP_KERNEL);
    182	if (!qentry)
    183		return -ENOMEM;
    184
    185	/* Lock the event queue before we read the local link status */
    186	spin_lock_irqsave(&rvu->cgx_evq_lock, flags);
    187	err = cgx_get_link_info(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
    188				&qentry->link_event.link_uinfo);
    189	qentry->link_event.cgx_id = cgx_id;
    190	qentry->link_event.lmac_id = lmac_id;
    191	if (err) {
    192		kfree(qentry);
    193		goto skip_add;
    194	}
    195	list_add_tail(&qentry->evq_node, &rvu->cgx_evq_head);
    196skip_add:
    197	spin_unlock_irqrestore(&rvu->cgx_evq_lock, flags);
    198
    199	/* start worker to process the events */
    200	queue_work(rvu->cgx_evh_wq, &rvu->cgx_evh_work);
    201
    202	return 0;
    203}
    204
    205/* This is called from interrupt context and is expected to be atomic */
    206static int cgx_lmac_postevent(struct cgx_link_event *event, void *data)
    207{
    208	struct cgx_evq_entry *qentry;
    209	struct rvu *rvu = data;
    210
    211	/* post event to the event queue */
    212	qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC);
    213	if (!qentry)
    214		return -ENOMEM;
    215	qentry->link_event = *event;
    216	spin_lock(&rvu->cgx_evq_lock);
    217	list_add_tail(&qentry->evq_node, &rvu->cgx_evq_head);
    218	spin_unlock(&rvu->cgx_evq_lock);
    219
    220	/* start worker to process the events */
    221	queue_work(rvu->cgx_evh_wq, &rvu->cgx_evh_work);
    222
    223	return 0;
    224}
    225
    226static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
    227{
    228	struct cgx_link_user_info *linfo;
    229	struct cgx_link_info_msg *msg;
    230	unsigned long pfmap;
    231	int err, pfid;
    232
    233	linfo = &event->link_uinfo;
    234	pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id);
    235
    236	do {
    237		pfid = find_first_bit(&pfmap, 16);
    238		clear_bit(pfid, &pfmap);
    239
    240		/* check if notification is enabled */
    241		if (!test_bit(pfid, &rvu->pf_notify_bmap)) {
    242			dev_info(rvu->dev, "cgx %d: lmac %d Link status %s\n",
    243				 event->cgx_id, event->lmac_id,
    244				 linfo->link_up ? "UP" : "DOWN");
    245			continue;
    246		}
    247
    248		/* Send mbox message to PF */
    249		msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid);
    250		if (!msg)
    251			continue;
    252		msg->link_info = *linfo;
    253		otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid);
    254		err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
    255		if (err)
    256			dev_warn(rvu->dev, "notification to pf %d failed\n",
    257				 pfid);
    258	} while (pfmap);
    259}
    260
    261static void cgx_evhandler_task(struct work_struct *work)
    262{
    263	struct rvu *rvu = container_of(work, struct rvu, cgx_evh_work);
    264	struct cgx_evq_entry *qentry;
    265	struct cgx_link_event *event;
    266	unsigned long flags;
    267
    268	do {
    269		/* Dequeue an event */
    270		spin_lock_irqsave(&rvu->cgx_evq_lock, flags);
    271		qentry = list_first_entry_or_null(&rvu->cgx_evq_head,
    272						  struct cgx_evq_entry,
    273						  evq_node);
    274		if (qentry)
    275			list_del(&qentry->evq_node);
    276		spin_unlock_irqrestore(&rvu->cgx_evq_lock, flags);
    277		if (!qentry)
    278			break; /* nothing more to process */
    279
    280		event = &qentry->link_event;
    281
    282		/* process event */
    283		cgx_notify_pfs(event, rvu);
    284		kfree(qentry);
    285	} while (1);
    286}
    287
    288static int cgx_lmac_event_handler_init(struct rvu *rvu)
    289{
    290	unsigned long lmac_bmap;
    291	struct cgx_event_cb cb;
    292	int cgx, lmac, err;
    293	void *cgxd;
    294
    295	spin_lock_init(&rvu->cgx_evq_lock);
    296	INIT_LIST_HEAD(&rvu->cgx_evq_head);
    297	INIT_WORK(&rvu->cgx_evh_work, cgx_evhandler_task);
    298	rvu->cgx_evh_wq = alloc_workqueue("rvu_evh_wq", 0, 0);
    299	if (!rvu->cgx_evh_wq) {
    300		dev_err(rvu->dev, "alloc workqueue failed");
    301		return -ENOMEM;
    302	}
    303
    304	cb.notify_link_chg = cgx_lmac_postevent; /* link change call back */
    305	cb.data = rvu;
    306
    307	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
    308		cgxd = rvu_cgx_pdata(cgx, rvu);
    309		if (!cgxd)
    310			continue;
    311		lmac_bmap = cgx_get_lmac_bmap(cgxd);
    312		for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX) {
    313			err = cgx_lmac_evh_register(&cb, cgxd, lmac);
    314			if (err)
    315				dev_err(rvu->dev,
    316					"%d:%d handler register failed\n",
    317					cgx, lmac);
    318		}
    319	}
    320
    321	return 0;
    322}
    323
    324static void rvu_cgx_wq_destroy(struct rvu *rvu)
    325{
    326	if (rvu->cgx_evh_wq) {
    327		destroy_workqueue(rvu->cgx_evh_wq);
    328		rvu->cgx_evh_wq = NULL;
    329	}
    330}
    331
    332int rvu_cgx_init(struct rvu *rvu)
    333{
    334	int cgx, err;
    335	void *cgxd;
    336
    337	/* CGX port id starts from 0 and are not necessarily contiguous
    338	 * Hence we allocate resources based on the maximum port id value.
    339	 */
    340	rvu->cgx_cnt_max = cgx_get_cgxcnt_max();
    341	if (!rvu->cgx_cnt_max) {
    342		dev_info(rvu->dev, "No CGX devices found!\n");
    343		return -ENODEV;
    344	}
    345
    346	rvu->cgx_idmap = devm_kzalloc(rvu->dev, rvu->cgx_cnt_max *
    347				      sizeof(void *), GFP_KERNEL);
    348	if (!rvu->cgx_idmap)
    349		return -ENOMEM;
    350
    351	/* Initialize the cgxdata table */
    352	for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++)
    353		rvu->cgx_idmap[cgx] = cgx_get_pdata(cgx);
    354
    355	/* Map CGX LMAC interfaces to RVU PFs */
    356	err = rvu_map_cgx_lmac_pf(rvu);
    357	if (err)
    358		return err;
    359
    360	/* Register for CGX events */
    361	err = cgx_lmac_event_handler_init(rvu);
    362	if (err)
    363		return err;
    364
    365	mutex_init(&rvu->cgx_cfg_lock);
    366
    367	/* Ensure event handler registration is completed, before
    368	 * we turn on the links
    369	 */
    370	mb();
    371
    372	/* Do link up for all CGX ports */
    373	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
    374		cgxd = rvu_cgx_pdata(cgx, rvu);
    375		if (!cgxd)
    376			continue;
    377		err = cgx_lmac_linkup_start(cgxd);
    378		if (err)
    379			dev_err(rvu->dev,
    380				"Link up process failed to start on cgx %d\n",
    381				cgx);
    382	}
    383
    384	return 0;
    385}
    386
    387int rvu_cgx_exit(struct rvu *rvu)
    388{
    389	unsigned long lmac_bmap;
    390	int cgx, lmac;
    391	void *cgxd;
    392
    393	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
    394		cgxd = rvu_cgx_pdata(cgx, rvu);
    395		if (!cgxd)
    396			continue;
    397		lmac_bmap = cgx_get_lmac_bmap(cgxd);
    398		for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX)
    399			cgx_lmac_evh_unregister(cgxd, lmac);
    400	}
    401
    402	/* Ensure event handler unregister is completed */
    403	mb();
    404
    405	rvu_cgx_wq_destroy(rvu);
    406	return 0;
    407}
    408
    409/* Most of the CGX configuration is restricted to the mapped PF only,
    410 * VF's of mapped PF and other PFs are not allowed. This fn() checks
    411 * whether a PFFUNC is permitted to do the config or not.
    412 */
    413inline bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
    414{
    415	if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
    416	    !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
    417		return false;
    418	return true;
    419}
    420
    421void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable)
    422{
    423	struct mac_ops *mac_ops;
    424	u8 cgx_id, lmac_id;
    425	void *cgxd;
    426
    427	if (!is_pf_cgxmapped(rvu, pf))
    428		return;
    429
    430	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    431	cgxd = rvu_cgx_pdata(cgx_id, rvu);
    432
    433	mac_ops = get_mac_ops(cgxd);
    434	/* Set / clear CTL_BCK to control pause frame forwarding to NIX */
    435	if (enable)
    436		mac_ops->mac_enadis_rx_pause_fwding(cgxd, lmac_id, true);
    437	else
    438		mac_ops->mac_enadis_rx_pause_fwding(cgxd, lmac_id, false);
    439}
    440
    441int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
    442{
    443	int pf = rvu_get_pf(pcifunc);
    444	struct mac_ops *mac_ops;
    445	u8 cgx_id, lmac_id;
    446	void *cgxd;
    447
    448	if (!is_cgx_config_permitted(rvu, pcifunc))
    449		return LMAC_AF_ERR_PERM_DENIED;
    450
    451	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    452	cgxd = rvu_cgx_pdata(cgx_id, rvu);
    453	mac_ops = get_mac_ops(cgxd);
    454
    455	return mac_ops->mac_rx_tx_enable(cgxd, lmac_id, start);
    456}
    457
    458int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable)
    459{
    460	struct mac_ops *mac_ops;
    461
    462	mac_ops = get_mac_ops(cgxd);
    463	return mac_ops->mac_tx_enable(cgxd, lmac_id, enable);
    464}
    465
    466void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
    467{
    468	int pf = rvu_get_pf(pcifunc);
    469	int i = 0, lmac_count = 0;
    470	u8 max_dmac_filters;
    471	u8 cgx_id, lmac_id;
    472	void *cgx_dev;
    473
    474	if (!is_cgx_config_permitted(rvu, pcifunc))
    475		return;
    476
    477	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    478	cgx_dev = cgx_get_pdata(cgx_id);
    479	lmac_count = cgx_get_lmac_cnt(cgx_dev);
    480	max_dmac_filters = MAX_DMAC_ENTRIES_PER_CGX / lmac_count;
    481
    482	for (i = 0; i < max_dmac_filters; i++)
    483		cgx_lmac_addr_del(cgx_id, lmac_id, i);
    484
    485	/* As cgx_lmac_addr_del does not clear entry for index 0
    486	 * so it needs to be done explicitly
    487	 */
    488	cgx_lmac_addr_reset(cgx_id, lmac_id);
    489}
    490
    491int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
    492				    struct msg_rsp *rsp)
    493{
    494	rvu_cgx_config_rxtx(rvu, req->hdr.pcifunc, true);
    495	return 0;
    496}
    497
    498int rvu_mbox_handler_cgx_stop_rxtx(struct rvu *rvu, struct msg_req *req,
    499				   struct msg_rsp *rsp)
    500{
    501	rvu_cgx_config_rxtx(rvu, req->hdr.pcifunc, false);
    502	return 0;
    503}
    504
    505static int rvu_lmac_get_stats(struct rvu *rvu, struct msg_req *req,
    506			      void *rsp)
    507{
    508	int pf = rvu_get_pf(req->hdr.pcifunc);
    509	struct mac_ops *mac_ops;
    510	int stat = 0, err = 0;
    511	u64 tx_stat, rx_stat;
    512	u8 cgx_idx, lmac;
    513	void *cgxd;
    514
    515	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    516		return LMAC_AF_ERR_PERM_DENIED;
    517
    518	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
    519	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
    520	mac_ops = get_mac_ops(cgxd);
    521
    522	/* Rx stats */
    523	while (stat < mac_ops->rx_stats_cnt) {
    524		err = mac_ops->mac_get_rx_stats(cgxd, lmac, stat, &rx_stat);
    525		if (err)
    526			return err;
    527		if (mac_ops->rx_stats_cnt == RPM_RX_STATS_COUNT)
    528			((struct rpm_stats_rsp *)rsp)->rx_stats[stat] = rx_stat;
    529		else
    530			((struct cgx_stats_rsp *)rsp)->rx_stats[stat] = rx_stat;
    531		stat++;
    532	}
    533
    534	/* Tx stats */
    535	stat = 0;
    536	while (stat < mac_ops->tx_stats_cnt) {
    537		err = mac_ops->mac_get_tx_stats(cgxd, lmac, stat, &tx_stat);
    538		if (err)
    539			return err;
    540		if (mac_ops->tx_stats_cnt == RPM_TX_STATS_COUNT)
    541			((struct rpm_stats_rsp *)rsp)->tx_stats[stat] = tx_stat;
    542		else
    543			((struct cgx_stats_rsp *)rsp)->tx_stats[stat] = tx_stat;
    544		stat++;
    545	}
    546	return 0;
    547}
    548
    549int rvu_mbox_handler_cgx_stats(struct rvu *rvu, struct msg_req *req,
    550			       struct cgx_stats_rsp *rsp)
    551{
    552	return rvu_lmac_get_stats(rvu, req, (void *)rsp);
    553}
    554
    555int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
    556			       struct rpm_stats_rsp *rsp)
    557{
    558	return rvu_lmac_get_stats(rvu, req, (void *)rsp);
    559}
    560
    561int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
    562				   struct msg_req *req,
    563				   struct cgx_fec_stats_rsp *rsp)
    564{
    565	int pf = rvu_get_pf(req->hdr.pcifunc);
    566	u8 cgx_idx, lmac;
    567	void *cgxd;
    568
    569	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    570		return LMAC_AF_ERR_PERM_DENIED;
    571	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
    572
    573	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
    574	return cgx_get_fec_stats(cgxd, lmac, rsp);
    575}
    576
    577int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
    578				      struct cgx_mac_addr_set_or_get *req,
    579				      struct cgx_mac_addr_set_or_get *rsp)
    580{
    581	int pf = rvu_get_pf(req->hdr.pcifunc);
    582	u8 cgx_id, lmac_id;
    583
    584	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    585		return -EPERM;
    586
    587	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    588
    589	cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);
    590
    591	return 0;
    592}
    593
    594int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
    595				      struct cgx_mac_addr_add_req *req,
    596				      struct cgx_mac_addr_add_rsp *rsp)
    597{
    598	int pf = rvu_get_pf(req->hdr.pcifunc);
    599	u8 cgx_id, lmac_id;
    600	int rc = 0;
    601
    602	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    603		return -EPERM;
    604
    605	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    606	rc = cgx_lmac_addr_add(cgx_id, lmac_id, req->mac_addr);
    607	if (rc >= 0) {
    608		rsp->index = rc;
    609		return 0;
    610	}
    611
    612	return rc;
    613}
    614
    615int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
    616				      struct cgx_mac_addr_del_req *req,
    617				      struct msg_rsp *rsp)
    618{
    619	int pf = rvu_get_pf(req->hdr.pcifunc);
    620	u8 cgx_id, lmac_id;
    621
    622	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    623		return -EPERM;
    624
    625	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    626	return cgx_lmac_addr_del(cgx_id, lmac_id, req->index);
    627}
    628
    629int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
    630					     struct msg_req *req,
    631					     struct cgx_max_dmac_entries_get_rsp
    632					     *rsp)
    633{
    634	int pf = rvu_get_pf(req->hdr.pcifunc);
    635	u8 cgx_id, lmac_id;
    636
    637	/* If msg is received from PFs(which are not mapped to CGX LMACs)
    638	 * or VF then no entries are allocated for DMAC filters at CGX level.
    639	 * So returning zero.
    640	 */
    641	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) {
    642		rsp->max_dmac_filters = 0;
    643		return 0;
    644	}
    645
    646	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    647	rsp->max_dmac_filters = cgx_lmac_addr_max_entries_get(cgx_id, lmac_id);
    648	return 0;
    649}
    650
    651int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
    652				      struct cgx_mac_addr_set_or_get *req,
    653				      struct cgx_mac_addr_set_or_get *rsp)
    654{
    655	int pf = rvu_get_pf(req->hdr.pcifunc);
    656	u8 cgx_id, lmac_id;
    657	int rc = 0, i;
    658	u64 cfg;
    659
    660	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    661		return -EPERM;
    662
    663	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    664
    665	rsp->hdr.rc = rc;
    666	cfg = cgx_lmac_addr_get(cgx_id, lmac_id);
    667	/* copy 48 bit mac address to req->mac_addr */
    668	for (i = 0; i < ETH_ALEN; i++)
    669		rsp->mac_addr[i] = cfg >> (ETH_ALEN - 1 - i) * 8;
    670	return 0;
    671}
    672
    673int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
    674					struct msg_rsp *rsp)
    675{
    676	u16 pcifunc = req->hdr.pcifunc;
    677	int pf = rvu_get_pf(pcifunc);
    678	u8 cgx_id, lmac_id;
    679
    680	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    681		return -EPERM;
    682
    683	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    684
    685	cgx_lmac_promisc_config(cgx_id, lmac_id, true);
    686	return 0;
    687}
    688
    689int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
    690					 struct msg_rsp *rsp)
    691{
    692	int pf = rvu_get_pf(req->hdr.pcifunc);
    693	u8 cgx_id, lmac_id;
    694
    695	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
    696		return -EPERM;
    697
    698	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    699
    700	cgx_lmac_promisc_config(cgx_id, lmac_id, false);
    701	return 0;
    702}
    703
    704static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
    705{
    706	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
    707	int pf = rvu_get_pf(pcifunc);
    708	struct mac_ops *mac_ops;
    709	u8 cgx_id, lmac_id;
    710	void *cgxd;
    711
    712	if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
    713		return 0;
    714
    715	/* This msg is expected only from PFs that are mapped to CGX LMACs,
    716	 * if received from other PF/VF simply ACK, nothing to do.
    717	 */
    718	if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
    719	    !is_pf_cgxmapped(rvu, pf))
    720		return -ENODEV;
    721
    722	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    723	cgxd = rvu_cgx_pdata(cgx_id, rvu);
    724
    725	mac_ops = get_mac_ops(cgxd);
    726	mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, true);
    727	/* If PTP is enabled then inform NPC that packets to be
    728	 * parsed by this PF will have their data shifted by 8 bytes
    729	 * and if PTP is disabled then no shift is required
    730	 */
    731	if (npc_config_ts_kpuaction(rvu, pf, pcifunc, enable))
    732		return -EINVAL;
    733	/* This flag is required to clean up CGX conf if app gets killed */
    734	pfvf->hw_rx_tstamp_en = enable;
    735
    736	return 0;
    737}
    738
    739int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
    740				       struct msg_rsp *rsp)
    741{
    742	if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
    743		return -EPERM;
    744
    745	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
    746}
    747
    748int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
    749					struct msg_rsp *rsp)
    750{
    751	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, false);
    752}
    753
    754static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
    755{
    756	int pf = rvu_get_pf(pcifunc);
    757	u8 cgx_id, lmac_id;
    758
    759	if (!is_cgx_config_permitted(rvu, pcifunc))
    760		return -EPERM;
    761
    762	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    763
    764	if (en) {
    765		set_bit(pf, &rvu->pf_notify_bmap);
    766		/* Send the current link status to PF */
    767		rvu_cgx_send_link_info(cgx_id, lmac_id, rvu);
    768	} else {
    769		clear_bit(pf, &rvu->pf_notify_bmap);
    770	}
    771
    772	return 0;
    773}
    774
    775int rvu_mbox_handler_cgx_start_linkevents(struct rvu *rvu, struct msg_req *req,
    776					  struct msg_rsp *rsp)
    777{
    778	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, true);
    779	return 0;
    780}
    781
    782int rvu_mbox_handler_cgx_stop_linkevents(struct rvu *rvu, struct msg_req *req,
    783					 struct msg_rsp *rsp)
    784{
    785	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, false);
    786	return 0;
    787}
    788
    789int rvu_mbox_handler_cgx_get_linkinfo(struct rvu *rvu, struct msg_req *req,
    790				      struct cgx_link_info_msg *rsp)
    791{
    792	u8 cgx_id, lmac_id;
    793	int pf, err;
    794
    795	pf = rvu_get_pf(req->hdr.pcifunc);
    796
    797	if (!is_pf_cgxmapped(rvu, pf))
    798		return -ENODEV;
    799
    800	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    801
    802	err = cgx_get_link_info(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
    803				&rsp->link_info);
    804	return err;
    805}
    806
    807int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
    808				      struct msg_req *req,
    809				      struct cgx_features_info_msg *rsp)
    810{
    811	int pf = rvu_get_pf(req->hdr.pcifunc);
    812	u8 cgx_idx, lmac;
    813	void *cgxd;
    814
    815	if (!is_pf_cgxmapped(rvu, pf))
    816		return 0;
    817
    818	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
    819	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
    820	rsp->lmac_features = cgx_features_get(cgxd);
    821
    822	return 0;
    823}
    824
    825u32 rvu_cgx_get_fifolen(struct rvu *rvu)
    826{
    827	struct mac_ops *mac_ops;
    828	u32 fifo_len;
    829
    830	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
    831	fifo_len = mac_ops ? mac_ops->fifo_len : 0;
    832
    833	return fifo_len;
    834}
    835
    836static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
    837{
    838	int pf = rvu_get_pf(pcifunc);
    839	struct mac_ops *mac_ops;
    840	u8 cgx_id, lmac_id;
    841
    842	if (!is_cgx_config_permitted(rvu, pcifunc))
    843		return -EPERM;
    844
    845	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    846	mac_ops = get_mac_ops(rvu_cgx_pdata(cgx_id, rvu));
    847
    848	return mac_ops->mac_lmac_intl_lbk(rvu_cgx_pdata(cgx_id, rvu),
    849					  lmac_id, en);
    850}
    851
    852int rvu_mbox_handler_cgx_intlbk_enable(struct rvu *rvu, struct msg_req *req,
    853				       struct msg_rsp *rsp)
    854{
    855	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, true);
    856	return 0;
    857}
    858
    859int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
    860					struct msg_rsp *rsp)
    861{
    862	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, false);
    863	return 0;
    864}
    865
    866int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause)
    867{
    868	int pf = rvu_get_pf(pcifunc);
    869	u8 rx_pfc = 0, tx_pfc = 0;
    870	struct mac_ops *mac_ops;
    871	u8 cgx_id, lmac_id;
    872	void *cgxd;
    873
    874	if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_FC))
    875		return 0;
    876
    877	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
    878	 * if received from other PF/VF simply ACK, nothing to do.
    879	 */
    880	if (!is_pf_cgxmapped(rvu, pf))
    881		return LMAC_AF_ERR_PF_NOT_MAPPED;
    882
    883	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    884	cgxd = rvu_cgx_pdata(cgx_id, rvu);
    885	mac_ops = get_mac_ops(cgxd);
    886
    887	mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &tx_pfc, &rx_pfc);
    888	if (tx_pfc || rx_pfc) {
    889		dev_warn(rvu->dev,
    890			 "Can not configure 802.3X flow control as PFC frames are enabled");
    891		return LMAC_AF_ERR_8023PAUSE_ENADIS_PERM_DENIED;
    892	}
    893
    894	mutex_lock(&rvu->rsrc_lock);
    895	if (verify_lmac_fc_cfg(cgxd, lmac_id, tx_pause, rx_pause,
    896			       pcifunc & RVU_PFVF_FUNC_MASK)) {
    897		mutex_unlock(&rvu->rsrc_lock);
    898		return LMAC_AF_ERR_PERM_DENIED;
    899	}
    900	mutex_unlock(&rvu->rsrc_lock);
    901
    902	return mac_ops->mac_enadis_pause_frm(cgxd, lmac_id, tx_pause, rx_pause);
    903}
    904
    905int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
    906				       struct cgx_pause_frm_cfg *req,
    907				       struct cgx_pause_frm_cfg *rsp)
    908{
    909	int pf = rvu_get_pf(req->hdr.pcifunc);
    910	struct mac_ops *mac_ops;
    911	u8 cgx_id, lmac_id;
    912	int err = 0;
    913	void *cgxd;
    914
    915	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
    916	 * if received from other PF/VF simply ACK, nothing to do.
    917	 */
    918	if (!is_pf_cgxmapped(rvu, pf))
    919		return -ENODEV;
    920
    921	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    922	cgxd = rvu_cgx_pdata(cgx_id, rvu);
    923	mac_ops = get_mac_ops(cgxd);
    924
    925	if (req->set)
    926		err = rvu_cgx_cfg_pause_frm(rvu, req->hdr.pcifunc, req->tx_pause, req->rx_pause);
    927	else
    928		mac_ops->mac_get_pause_frm_status(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
    929
    930	return err;
    931}
    932
    933int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
    934					   struct msg_rsp *rsp)
    935{
    936	int pf = rvu_get_pf(req->hdr.pcifunc);
    937	u8 cgx_id, lmac_id;
    938
    939	if (!is_pf_cgxmapped(rvu, pf))
    940		return LMAC_AF_ERR_PF_NOT_MAPPED;
    941
    942	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
    943	return cgx_get_phy_fec_stats(rvu_cgx_pdata(cgx_id, rvu), lmac_id);
    944}
    945
    946/* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
    947 * from its VFs as well. ie. NIX rx/tx counters at the CGX port level
    948 */
    949int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
    950			   int index, int rxtxflag, u64 *stat)
    951{
    952	struct rvu_block *block;
    953	int blkaddr;
    954	u16 pcifunc;
    955	int pf, lf;
    956
    957	*stat = 0;
    958
    959	if (!cgxd || !rvu)
    960		return -EINVAL;
    961
    962	pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
    963	if (pf < 0)
    964		return pf;
    965
    966	/* Assumes LF of a PF and all of its VF belongs to the same
    967	 * NIX block
    968	 */
    969	pcifunc = pf << RVU_PFVF_PF_SHIFT;
    970	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
    971	if (blkaddr < 0)
    972		return 0;
    973	block = &rvu->hw->block[blkaddr];
    974
    975	for (lf = 0; lf < block->lf.max; lf++) {
    976		/* Check if a lf is attached to this PF or one of its VFs */
    977		if (!((block->fn_map[lf] & ~RVU_PFVF_FUNC_MASK) == (pcifunc &
    978			 ~RVU_PFVF_FUNC_MASK)))
    979			continue;
    980		if (rxtxflag == NIX_STATS_RX)
    981			*stat += rvu_read64(rvu, blkaddr,
    982					    NIX_AF_LFX_RX_STATX(lf, index));
    983		else
    984			*stat += rvu_read64(rvu, blkaddr,
    985					    NIX_AF_LFX_TX_STATX(lf, index));
    986	}
    987
    988	return 0;
    989}
    990
    991int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
    992{
    993	struct rvu_pfvf *parent_pf, *pfvf;
    994	int cgx_users, err = 0;
    995
    996	if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
    997		return 0;
    998
    999	parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
   1000	pfvf = rvu_get_pfvf(rvu, pcifunc);
   1001
   1002	mutex_lock(&rvu->cgx_cfg_lock);
   1003
   1004	if (start && pfvf->cgx_in_use)
   1005		goto exit;  /* CGX is already started hence nothing to do */
   1006	if (!start && !pfvf->cgx_in_use)
   1007		goto exit; /* CGX is already stopped hence nothing to do */
   1008
   1009	if (start) {
   1010		cgx_users = parent_pf->cgx_users;
   1011		parent_pf->cgx_users++;
   1012	} else {
   1013		parent_pf->cgx_users--;
   1014		cgx_users = parent_pf->cgx_users;
   1015	}
   1016
   1017	/* Start CGX when first of all NIXLFs is started.
   1018	 * Stop CGX when last of all NIXLFs is stopped.
   1019	 */
   1020	if (!cgx_users) {
   1021		err = rvu_cgx_config_rxtx(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK,
   1022					  start);
   1023		if (err) {
   1024			dev_err(rvu->dev, "Unable to %s CGX\n",
   1025				start ? "start" : "stop");
   1026			/* Revert the usage count in case of error */
   1027			parent_pf->cgx_users = start ? parent_pf->cgx_users  - 1
   1028					       : parent_pf->cgx_users  + 1;
   1029			goto exit;
   1030		}
   1031	}
   1032	pfvf->cgx_in_use = start;
   1033exit:
   1034	mutex_unlock(&rvu->cgx_cfg_lock);
   1035	return err;
   1036}
   1037
   1038int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
   1039				       struct fec_mode *req,
   1040				       struct fec_mode *rsp)
   1041{
   1042	int pf = rvu_get_pf(req->hdr.pcifunc);
   1043	u8 cgx_id, lmac_id;
   1044
   1045	if (!is_pf_cgxmapped(rvu, pf))
   1046		return -EPERM;
   1047
   1048	if (req->fec == OTX2_FEC_OFF)
   1049		req->fec = OTX2_FEC_NONE;
   1050	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1051	rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
   1052	return 0;
   1053}
   1054
   1055int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
   1056					   struct cgx_fw_data *rsp)
   1057{
   1058	int pf = rvu_get_pf(req->hdr.pcifunc);
   1059	u8 cgx_id, lmac_id;
   1060
   1061	if (!rvu->fwdata)
   1062		return -ENXIO;
   1063
   1064	if (!is_pf_cgxmapped(rvu, pf))
   1065		return -EPERM;
   1066
   1067	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1068
   1069	memcpy(&rsp->fwdata, &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id],
   1070	       sizeof(struct cgx_lmac_fwdata_s));
   1071	return 0;
   1072}
   1073
   1074int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
   1075				       struct cgx_set_link_mode_req *req,
   1076				       struct cgx_set_link_mode_rsp *rsp)
   1077{
   1078	int pf = rvu_get_pf(req->hdr.pcifunc);
   1079	u8 cgx_idx, lmac;
   1080	void *cgxd;
   1081
   1082	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
   1083		return -EPERM;
   1084
   1085	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
   1086	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
   1087	rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac);
   1088	return 0;
   1089}
   1090
   1091int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct msg_req *req,
   1092					struct msg_rsp *rsp)
   1093{
   1094	int pf = rvu_get_pf(req->hdr.pcifunc);
   1095	u8 cgx_id, lmac_id;
   1096
   1097	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
   1098		return LMAC_AF_ERR_PERM_DENIED;
   1099
   1100	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1101	return cgx_lmac_addr_reset(cgx_id, lmac_id);
   1102}
   1103
   1104int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
   1105					 struct cgx_mac_addr_update_req *req,
   1106					 struct msg_rsp *rsp)
   1107{
   1108	int pf = rvu_get_pf(req->hdr.pcifunc);
   1109	u8 cgx_id, lmac_id;
   1110
   1111	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
   1112		return LMAC_AF_ERR_PERM_DENIED;
   1113
   1114	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1115	return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
   1116}
   1117
   1118int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause,
   1119			       u8 rx_pause, u16 pfc_en)
   1120{
   1121	int pf = rvu_get_pf(pcifunc);
   1122	u8 rx_8023 = 0, tx_8023 = 0;
   1123	struct mac_ops *mac_ops;
   1124	u8 cgx_id, lmac_id;
   1125	void *cgxd;
   1126
   1127	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
   1128	 * if received from other PF/VF simply ACK, nothing to do.
   1129	 */
   1130	if (!is_pf_cgxmapped(rvu, pf))
   1131		return -ENODEV;
   1132
   1133	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1134	cgxd = rvu_cgx_pdata(cgx_id, rvu);
   1135	mac_ops = get_mac_ops(cgxd);
   1136
   1137	mac_ops->mac_get_pause_frm_status(cgxd, lmac_id, &tx_8023, &rx_8023);
   1138	if (tx_8023 || rx_8023) {
   1139		dev_warn(rvu->dev,
   1140			 "Can not configure PFC as 802.3X pause frames are enabled");
   1141		return LMAC_AF_ERR_PFC_ENADIS_PERM_DENIED;
   1142	}
   1143
   1144	mutex_lock(&rvu->rsrc_lock);
   1145	if (verify_lmac_fc_cfg(cgxd, lmac_id, tx_pause, rx_pause,
   1146			       pcifunc & RVU_PFVF_FUNC_MASK)) {
   1147		mutex_unlock(&rvu->rsrc_lock);
   1148		return LMAC_AF_ERR_PERM_DENIED;
   1149	}
   1150	mutex_unlock(&rvu->rsrc_lock);
   1151
   1152	return mac_ops->pfc_config(cgxd, lmac_id, tx_pause, rx_pause, pfc_en);
   1153}
   1154
   1155int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
   1156					    struct cgx_pfc_cfg *req,
   1157					    struct cgx_pfc_rsp *rsp)
   1158{
   1159	int pf = rvu_get_pf(req->hdr.pcifunc);
   1160	struct mac_ops *mac_ops;
   1161	u8 cgx_id, lmac_id;
   1162	void *cgxd;
   1163	int err;
   1164
   1165	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
   1166	 * if received from other PF/VF simply ACK, nothing to do.
   1167	 */
   1168	if (!is_pf_cgxmapped(rvu, pf))
   1169		return -ENODEV;
   1170
   1171	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
   1172	cgxd = rvu_cgx_pdata(cgx_id, rvu);
   1173	mac_ops = get_mac_ops(cgxd);
   1174
   1175	err = rvu_cgx_prio_flow_ctrl_cfg(rvu, req->hdr.pcifunc, req->tx_pause,
   1176					 req->rx_pause, req->pfc_en);
   1177
   1178	mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
   1179	return err;
   1180}