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 
is_mac_feature_supported(struct rvu * rvu,int pf,int feature)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 */
cgxlmac_to_pfmap(struct rvu * rvu,u8 cgx_id,u8 lmac_id)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 
cgxlmac_to_pf(struct rvu * rvu,int cgx_id,int lmac_id)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 
cgxlmac_id_to_bmap(u8 cgx_id,u8 lmac_id)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 
rvu_cgx_pdata(u8 cgx_id,struct rvu * rvu)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 */
rvu_first_cgx_pdata(struct rvu * rvu)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 */
rvu_map_cgx_nix_block(struct rvu * rvu,int pf,int cgx_id,int lmac_id)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 
rvu_map_cgx_lmac_pf(struct rvu * rvu)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 
rvu_cgx_send_link_info(int cgx_id,int lmac_id,struct rvu * rvu)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 */
cgx_lmac_postevent(struct cgx_link_event * event,void * data)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 
cgx_notify_pfs(struct cgx_link_event * event,struct rvu * rvu)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 
cgx_evhandler_task(struct work_struct * work)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 
cgx_lmac_event_handler_init(struct rvu * rvu)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 
rvu_cgx_wq_destroy(struct rvu * rvu)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 
rvu_cgx_init(struct rvu * rvu)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 
rvu_cgx_exit(struct rvu * rvu)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  */
is_cgx_config_permitted(struct rvu * rvu,u16 pcifunc)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 
rvu_cgx_enadis_rx_bp(struct rvu * rvu,int pf,bool enable)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 
rvu_cgx_config_rxtx(struct rvu * rvu,u16 pcifunc,bool start)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 
rvu_cgx_config_tx(void * cgxd,int lmac_id,bool enable)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 
rvu_cgx_disable_dmac_entries(struct rvu * rvu,u16 pcifunc)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 
rvu_mbox_handler_cgx_start_rxtx(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)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 
rvu_mbox_handler_cgx_stop_rxtx(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)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 
rvu_lmac_get_stats(struct rvu * rvu,struct msg_req * req,void * rsp)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 
rvu_mbox_handler_cgx_stats(struct rvu * rvu,struct msg_req * req,struct cgx_stats_rsp * rsp)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 
rvu_mbox_handler_rpm_stats(struct rvu * rvu,struct msg_req * req,struct rpm_stats_rsp * rsp)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 
rvu_mbox_handler_cgx_fec_stats(struct rvu * rvu,struct msg_req * req,struct cgx_fec_stats_rsp * rsp)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 
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)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 
rvu_mbox_handler_cgx_mac_addr_add(struct rvu * rvu,struct cgx_mac_addr_add_req * req,struct cgx_mac_addr_add_rsp * rsp)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 
rvu_mbox_handler_cgx_mac_addr_del(struct rvu * rvu,struct cgx_mac_addr_del_req * req,struct msg_rsp * rsp)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 
rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu * rvu,struct msg_req * req,struct cgx_max_dmac_entries_get_rsp * rsp)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 
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)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 
rvu_mbox_handler_cgx_promisc_enable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)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 
rvu_mbox_handler_cgx_promisc_disable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)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 
rvu_cgx_ptp_rx_cfg(struct rvu * rvu,u16 pcifunc,bool enable)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 PFs that are mapped to CGX LMACs,
760 	 * if received from other PF/VF simply ACK, nothing to do.
761 	 */
762 	if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
763 	    !is_pf_cgxmapped(rvu, pf))
764 		return -ENODEV;
765 
766 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
767 	cgxd = rvu_cgx_pdata(cgx_id, rvu);
768 
769 	mac_ops = get_mac_ops(cgxd);
770 	mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, enable);
771 	/* If PTP is enabled then inform NPC that packets to be
772 	 * parsed by this PF will have their data shifted by 8 bytes
773 	 * and if PTP is disabled then no shift is required
774 	 */
775 	if (npc_config_ts_kpuaction(rvu, pf, pcifunc, enable))
776 		return -EINVAL;
777 	/* This flag is required to clean up CGX conf if app gets killed */
778 	pfvf->hw_rx_tstamp_en = enable;
779 
780 	/* Inform MCS about 8B RX header */
781 	rvu_mcs_ptp_cfg(rvu, cgx_id, lmac_id, enable);
782 	return 0;
783 }
784 
rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)785 int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
786 				       struct msg_rsp *rsp)
787 {
788 	if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
789 		return -EPERM;
790 
791 	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
792 }
793 
rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)794 int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
795 					struct msg_rsp *rsp)
796 {
797 	return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, false);
798 }
799 
rvu_cgx_config_linkevents(struct rvu * rvu,u16 pcifunc,bool en)800 static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
801 {
802 	int pf = rvu_get_pf(pcifunc);
803 	u8 cgx_id, lmac_id;
804 
805 	if (!is_cgx_config_permitted(rvu, pcifunc))
806 		return -EPERM;
807 
808 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
809 
810 	if (en) {
811 		set_bit(pf, &rvu->pf_notify_bmap);
812 		/* Send the current link status to PF */
813 		rvu_cgx_send_link_info(cgx_id, lmac_id, rvu);
814 	} else {
815 		clear_bit(pf, &rvu->pf_notify_bmap);
816 	}
817 
818 	return 0;
819 }
820 
rvu_mbox_handler_cgx_start_linkevents(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)821 int rvu_mbox_handler_cgx_start_linkevents(struct rvu *rvu, struct msg_req *req,
822 					  struct msg_rsp *rsp)
823 {
824 	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, true);
825 	return 0;
826 }
827 
rvu_mbox_handler_cgx_stop_linkevents(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)828 int rvu_mbox_handler_cgx_stop_linkevents(struct rvu *rvu, struct msg_req *req,
829 					 struct msg_rsp *rsp)
830 {
831 	rvu_cgx_config_linkevents(rvu, req->hdr.pcifunc, false);
832 	return 0;
833 }
834 
rvu_mbox_handler_cgx_get_linkinfo(struct rvu * rvu,struct msg_req * req,struct cgx_link_info_msg * rsp)835 int rvu_mbox_handler_cgx_get_linkinfo(struct rvu *rvu, struct msg_req *req,
836 				      struct cgx_link_info_msg *rsp)
837 {
838 	u8 cgx_id, lmac_id;
839 	int pf, err;
840 
841 	pf = rvu_get_pf(req->hdr.pcifunc);
842 
843 	if (!is_pf_cgxmapped(rvu, pf))
844 		return -ENODEV;
845 
846 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
847 
848 	err = cgx_get_link_info(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
849 				&rsp->link_info);
850 	return err;
851 }
852 
rvu_mbox_handler_cgx_features_get(struct rvu * rvu,struct msg_req * req,struct cgx_features_info_msg * rsp)853 int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
854 				      struct msg_req *req,
855 				      struct cgx_features_info_msg *rsp)
856 {
857 	int pf = rvu_get_pf(req->hdr.pcifunc);
858 	u8 cgx_idx, lmac;
859 	void *cgxd;
860 
861 	if (!is_pf_cgxmapped(rvu, pf))
862 		return 0;
863 
864 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
865 	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
866 	rsp->lmac_features = cgx_features_get(cgxd);
867 
868 	return 0;
869 }
870 
rvu_cgx_get_fifolen(struct rvu * rvu)871 u32 rvu_cgx_get_fifolen(struct rvu *rvu)
872 {
873 	struct mac_ops *mac_ops;
874 	u32 fifo_len;
875 
876 	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
877 	fifo_len = mac_ops ? mac_ops->fifo_len : 0;
878 
879 	return fifo_len;
880 }
881 
rvu_cgx_get_lmac_fifolen(struct rvu * rvu,int cgx,int lmac)882 u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
883 {
884 	struct mac_ops *mac_ops;
885 	void *cgxd;
886 
887 	cgxd = rvu_cgx_pdata(cgx, rvu);
888 	if (!cgxd)
889 		return 0;
890 
891 	mac_ops = get_mac_ops(cgxd);
892 	if (!mac_ops->lmac_fifo_len)
893 		return 0;
894 
895 	return mac_ops->lmac_fifo_len(cgxd, lmac);
896 }
897 
rvu_cgx_config_intlbk(struct rvu * rvu,u16 pcifunc,bool en)898 static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
899 {
900 	int pf = rvu_get_pf(pcifunc);
901 	struct mac_ops *mac_ops;
902 	u8 cgx_id, lmac_id;
903 
904 	if (!is_cgx_config_permitted(rvu, pcifunc))
905 		return -EPERM;
906 
907 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
908 	mac_ops = get_mac_ops(rvu_cgx_pdata(cgx_id, rvu));
909 
910 	return mac_ops->mac_lmac_intl_lbk(rvu_cgx_pdata(cgx_id, rvu),
911 					  lmac_id, en);
912 }
913 
rvu_mbox_handler_cgx_intlbk_enable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)914 int rvu_mbox_handler_cgx_intlbk_enable(struct rvu *rvu, struct msg_req *req,
915 				       struct msg_rsp *rsp)
916 {
917 	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, true);
918 	return 0;
919 }
920 
rvu_mbox_handler_cgx_intlbk_disable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)921 int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
922 					struct msg_rsp *rsp)
923 {
924 	rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, false);
925 	return 0;
926 }
927 
rvu_cgx_cfg_pause_frm(struct rvu * rvu,u16 pcifunc,u8 tx_pause,u8 rx_pause)928 int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause)
929 {
930 	int pf = rvu_get_pf(pcifunc);
931 	u8 rx_pfc = 0, tx_pfc = 0;
932 	struct mac_ops *mac_ops;
933 	u8 cgx_id, lmac_id;
934 	void *cgxd;
935 
936 	if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_FC))
937 		return 0;
938 
939 	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
940 	 * if received from other PF/VF simply ACK, nothing to do.
941 	 */
942 	if (!is_pf_cgxmapped(rvu, pf))
943 		return LMAC_AF_ERR_PF_NOT_MAPPED;
944 
945 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
946 	cgxd = rvu_cgx_pdata(cgx_id, rvu);
947 	mac_ops = get_mac_ops(cgxd);
948 
949 	mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &tx_pfc, &rx_pfc);
950 	if (tx_pfc || rx_pfc) {
951 		dev_warn(rvu->dev,
952 			 "Can not configure 802.3X flow control as PFC frames are enabled");
953 		return LMAC_AF_ERR_8023PAUSE_ENADIS_PERM_DENIED;
954 	}
955 
956 	mutex_lock(&rvu->rsrc_lock);
957 	if (verify_lmac_fc_cfg(cgxd, lmac_id, tx_pause, rx_pause,
958 			       pcifunc & RVU_PFVF_FUNC_MASK)) {
959 		mutex_unlock(&rvu->rsrc_lock);
960 		return LMAC_AF_ERR_PERM_DENIED;
961 	}
962 	mutex_unlock(&rvu->rsrc_lock);
963 
964 	return mac_ops->mac_enadis_pause_frm(cgxd, lmac_id, tx_pause, rx_pause);
965 }
966 
rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu * rvu,struct cgx_pause_frm_cfg * req,struct cgx_pause_frm_cfg * rsp)967 int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
968 				       struct cgx_pause_frm_cfg *req,
969 				       struct cgx_pause_frm_cfg *rsp)
970 {
971 	int pf = rvu_get_pf(req->hdr.pcifunc);
972 	struct mac_ops *mac_ops;
973 	u8 cgx_id, lmac_id;
974 	int err = 0;
975 	void *cgxd;
976 
977 	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
978 	 * if received from other PF/VF simply ACK, nothing to do.
979 	 */
980 	if (!is_pf_cgxmapped(rvu, pf))
981 		return -ENODEV;
982 
983 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
984 	cgxd = rvu_cgx_pdata(cgx_id, rvu);
985 	mac_ops = get_mac_ops(cgxd);
986 
987 	if (req->set)
988 		err = rvu_cgx_cfg_pause_frm(rvu, req->hdr.pcifunc, req->tx_pause, req->rx_pause);
989 	else
990 		mac_ops->mac_get_pause_frm_status(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
991 
992 	return err;
993 }
994 
rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)995 int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
996 					   struct msg_rsp *rsp)
997 {
998 	int pf = rvu_get_pf(req->hdr.pcifunc);
999 	u8 cgx_id, lmac_id;
1000 
1001 	if (!is_pf_cgxmapped(rvu, pf))
1002 		return LMAC_AF_ERR_PF_NOT_MAPPED;
1003 
1004 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1005 	return cgx_get_phy_fec_stats(rvu_cgx_pdata(cgx_id, rvu), lmac_id);
1006 }
1007 
1008 /* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
1009  * from its VFs as well. ie. NIX rx/tx counters at the CGX port level
1010  */
rvu_cgx_nix_cuml_stats(struct rvu * rvu,void * cgxd,int lmac_id,int index,int rxtxflag,u64 * stat)1011 int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
1012 			   int index, int rxtxflag, u64 *stat)
1013 {
1014 	struct rvu_block *block;
1015 	int blkaddr;
1016 	u16 pcifunc;
1017 	int pf, lf;
1018 
1019 	*stat = 0;
1020 
1021 	if (!cgxd || !rvu)
1022 		return -EINVAL;
1023 
1024 	pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
1025 	if (pf < 0)
1026 		return pf;
1027 
1028 	/* Assumes LF of a PF and all of its VF belongs to the same
1029 	 * NIX block
1030 	 */
1031 	pcifunc = pf << RVU_PFVF_PF_SHIFT;
1032 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
1033 	if (blkaddr < 0)
1034 		return 0;
1035 	block = &rvu->hw->block[blkaddr];
1036 
1037 	for (lf = 0; lf < block->lf.max; lf++) {
1038 		/* Check if a lf is attached to this PF or one of its VFs */
1039 		if (!((block->fn_map[lf] & ~RVU_PFVF_FUNC_MASK) == (pcifunc &
1040 			 ~RVU_PFVF_FUNC_MASK)))
1041 			continue;
1042 		if (rxtxflag == NIX_STATS_RX)
1043 			*stat += rvu_read64(rvu, blkaddr,
1044 					    NIX_AF_LFX_RX_STATX(lf, index));
1045 		else
1046 			*stat += rvu_read64(rvu, blkaddr,
1047 					    NIX_AF_LFX_TX_STATX(lf, index));
1048 	}
1049 
1050 	return 0;
1051 }
1052 
rvu_cgx_start_stop_io(struct rvu * rvu,u16 pcifunc,bool start)1053 int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
1054 {
1055 	struct rvu_pfvf *parent_pf, *pfvf;
1056 	int cgx_users, err = 0;
1057 
1058 	if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
1059 		return 0;
1060 
1061 	parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
1062 	pfvf = rvu_get_pfvf(rvu, pcifunc);
1063 
1064 	mutex_lock(&rvu->cgx_cfg_lock);
1065 
1066 	if (start && pfvf->cgx_in_use)
1067 		goto exit;  /* CGX is already started hence nothing to do */
1068 	if (!start && !pfvf->cgx_in_use)
1069 		goto exit; /* CGX is already stopped hence nothing to do */
1070 
1071 	if (start) {
1072 		cgx_users = parent_pf->cgx_users;
1073 		parent_pf->cgx_users++;
1074 	} else {
1075 		parent_pf->cgx_users--;
1076 		cgx_users = parent_pf->cgx_users;
1077 	}
1078 
1079 	/* Start CGX when first of all NIXLFs is started.
1080 	 * Stop CGX when last of all NIXLFs is stopped.
1081 	 */
1082 	if (!cgx_users) {
1083 		err = rvu_cgx_config_rxtx(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK,
1084 					  start);
1085 		if (err) {
1086 			dev_err(rvu->dev, "Unable to %s CGX\n",
1087 				start ? "start" : "stop");
1088 			/* Revert the usage count in case of error */
1089 			parent_pf->cgx_users = start ? parent_pf->cgx_users  - 1
1090 					       : parent_pf->cgx_users  + 1;
1091 			goto exit;
1092 		}
1093 	}
1094 	pfvf->cgx_in_use = start;
1095 exit:
1096 	mutex_unlock(&rvu->cgx_cfg_lock);
1097 	return err;
1098 }
1099 
rvu_mbox_handler_cgx_set_fec_param(struct rvu * rvu,struct fec_mode * req,struct fec_mode * rsp)1100 int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
1101 				       struct fec_mode *req,
1102 				       struct fec_mode *rsp)
1103 {
1104 	int pf = rvu_get_pf(req->hdr.pcifunc);
1105 	u8 cgx_id, lmac_id;
1106 
1107 	if (!is_pf_cgxmapped(rvu, pf))
1108 		return -EPERM;
1109 
1110 	if (req->fec == OTX2_FEC_OFF)
1111 		req->fec = OTX2_FEC_NONE;
1112 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1113 	rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
1114 	return 0;
1115 }
1116 
rvu_mbox_handler_cgx_get_aux_link_info(struct rvu * rvu,struct msg_req * req,struct cgx_fw_data * rsp)1117 int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
1118 					   struct cgx_fw_data *rsp)
1119 {
1120 	int pf = rvu_get_pf(req->hdr.pcifunc);
1121 	u8 cgx_id, lmac_id;
1122 
1123 	if (!rvu->fwdata)
1124 		return LMAC_AF_ERR_FIRMWARE_DATA_NOT_MAPPED;
1125 
1126 	if (!is_pf_cgxmapped(rvu, pf))
1127 		return -EPERM;
1128 
1129 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1130 
1131 	if (rvu->hw->lmac_per_cgx == CGX_LMACS_USX)
1132 		memcpy(&rsp->fwdata,
1133 		       &rvu->fwdata->cgx_fw_data_usx[cgx_id][lmac_id],
1134 		       sizeof(struct cgx_lmac_fwdata_s));
1135 	else
1136 		memcpy(&rsp->fwdata,
1137 		       &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id],
1138 		       sizeof(struct cgx_lmac_fwdata_s));
1139 
1140 	return 0;
1141 }
1142 
rvu_mbox_handler_cgx_set_link_mode(struct rvu * rvu,struct cgx_set_link_mode_req * req,struct cgx_set_link_mode_rsp * rsp)1143 int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
1144 				       struct cgx_set_link_mode_req *req,
1145 				       struct cgx_set_link_mode_rsp *rsp)
1146 {
1147 	int pf = rvu_get_pf(req->hdr.pcifunc);
1148 	u8 cgx_idx, lmac;
1149 	void *cgxd;
1150 
1151 	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
1152 		return -EPERM;
1153 
1154 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
1155 	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
1156 	rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac);
1157 	return 0;
1158 }
1159 
rvu_mbox_handler_cgx_mac_addr_reset(struct rvu * rvu,struct cgx_mac_addr_reset_req * req,struct msg_rsp * rsp)1160 int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
1161 					struct msg_rsp *rsp)
1162 {
1163 	int pf = rvu_get_pf(req->hdr.pcifunc);
1164 	u8 cgx_id, lmac_id;
1165 
1166 	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
1167 		return LMAC_AF_ERR_PERM_DENIED;
1168 
1169 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1170 
1171 	if (rvu_npc_exact_has_match_table(rvu))
1172 		return rvu_npc_exact_mac_addr_reset(rvu, req, rsp);
1173 
1174 	return cgx_lmac_addr_reset(cgx_id, lmac_id);
1175 }
1176 
rvu_mbox_handler_cgx_mac_addr_update(struct rvu * rvu,struct cgx_mac_addr_update_req * req,struct cgx_mac_addr_update_rsp * rsp)1177 int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
1178 					 struct cgx_mac_addr_update_req *req,
1179 					 struct cgx_mac_addr_update_rsp *rsp)
1180 {
1181 	int pf = rvu_get_pf(req->hdr.pcifunc);
1182 	u8 cgx_id, lmac_id;
1183 
1184 	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
1185 		return LMAC_AF_ERR_PERM_DENIED;
1186 
1187 	if (rvu_npc_exact_has_match_table(rvu))
1188 		return rvu_npc_exact_mac_addr_update(rvu, req, rsp);
1189 
1190 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1191 	return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
1192 }
1193 
rvu_cgx_prio_flow_ctrl_cfg(struct rvu * rvu,u16 pcifunc,u8 tx_pause,u8 rx_pause,u16 pfc_en)1194 int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause,
1195 			       u8 rx_pause, u16 pfc_en)
1196 {
1197 	int pf = rvu_get_pf(pcifunc);
1198 	u8 rx_8023 = 0, tx_8023 = 0;
1199 	struct mac_ops *mac_ops;
1200 	u8 cgx_id, lmac_id;
1201 	void *cgxd;
1202 
1203 	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
1204 	 * if received from other PF/VF simply ACK, nothing to do.
1205 	 */
1206 	if (!is_pf_cgxmapped(rvu, pf))
1207 		return -ENODEV;
1208 
1209 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1210 	cgxd = rvu_cgx_pdata(cgx_id, rvu);
1211 	mac_ops = get_mac_ops(cgxd);
1212 
1213 	mac_ops->mac_get_pause_frm_status(cgxd, lmac_id, &tx_8023, &rx_8023);
1214 	if (tx_8023 || rx_8023) {
1215 		dev_warn(rvu->dev,
1216 			 "Can not configure PFC as 802.3X pause frames are enabled");
1217 		return LMAC_AF_ERR_PFC_ENADIS_PERM_DENIED;
1218 	}
1219 
1220 	mutex_lock(&rvu->rsrc_lock);
1221 	if (verify_lmac_fc_cfg(cgxd, lmac_id, tx_pause, rx_pause,
1222 			       pcifunc & RVU_PFVF_FUNC_MASK)) {
1223 		mutex_unlock(&rvu->rsrc_lock);
1224 		return LMAC_AF_ERR_PERM_DENIED;
1225 	}
1226 	mutex_unlock(&rvu->rsrc_lock);
1227 
1228 	return mac_ops->pfc_config(cgxd, lmac_id, tx_pause, rx_pause, pfc_en);
1229 }
1230 
rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu * rvu,struct cgx_pfc_cfg * req,struct cgx_pfc_rsp * rsp)1231 int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
1232 					    struct cgx_pfc_cfg *req,
1233 					    struct cgx_pfc_rsp *rsp)
1234 {
1235 	int pf = rvu_get_pf(req->hdr.pcifunc);
1236 	struct mac_ops *mac_ops;
1237 	u8 cgx_id, lmac_id;
1238 	void *cgxd;
1239 	int err;
1240 
1241 	/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
1242 	 * if received from other PF/VF simply ACK, nothing to do.
1243 	 */
1244 	if (!is_pf_cgxmapped(rvu, pf))
1245 		return -ENODEV;
1246 
1247 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1248 	cgxd = rvu_cgx_pdata(cgx_id, rvu);
1249 	mac_ops = get_mac_ops(cgxd);
1250 
1251 	err = rvu_cgx_prio_flow_ctrl_cfg(rvu, req->hdr.pcifunc, req->tx_pause,
1252 					 req->rx_pause, req->pfc_en);
1253 
1254 	mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
1255 	return err;
1256 }
1257 
rvu_mac_reset(struct rvu * rvu,u16 pcifunc)1258 void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
1259 {
1260 	int pf = rvu_get_pf(pcifunc);
1261 	struct mac_ops *mac_ops;
1262 	struct cgx *cgxd;
1263 	u8 cgx, lmac;
1264 
1265 	if (!is_pf_cgxmapped(rvu, pf))
1266 		return;
1267 
1268 	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx, &lmac);
1269 	cgxd = rvu_cgx_pdata(cgx, rvu);
1270 	mac_ops = get_mac_ops(cgxd);
1271 
1272 	if (mac_ops->mac_reset(cgxd, lmac, !is_vf(pcifunc)))
1273 		dev_err(rvu->dev, "Failed to reset MAC\n");
1274 }
1275