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