1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell CN10K MCS driver
3  *
4  * Copyright (C) 2022 Marvell.
5  */
6 
7 #include <linux/types.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 
12 #include "mcs.h"
13 #include "rvu.h"
14 #include "mcs_reg.h"
15 #include "lmac_common.h"
16 
17 #define M(_name, _id, _fn_name, _req_type, _rsp_type)			\
18 static struct _req_type __maybe_unused					\
19 *otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid)		\
20 {									\
21 	struct _req_type *req;						\
22 									\
23 	req = (struct _req_type *)otx2_mbox_alloc_msg_rsp(		\
24 		&rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \
25 		sizeof(struct _rsp_type));				\
26 	if (!req)							\
27 		return NULL;						\
28 	req->hdr.sig = OTX2_MBOX_REQ_SIG;				\
29 	req->hdr.id = _id;						\
30 	return req;							\
31 }
32 
33 MBOX_UP_MCS_MESSAGES
34 #undef M
35 
36 void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena)
37 {
38 	struct mcs *mcs;
39 	u64 cfg;
40 	u8 port;
41 
42 	if (!rvu->mcs_blk_cnt)
43 		return;
44 
45 	/* When ptp is enabled, RPM appends 8B header for all
46 	 * RX packets. MCS PEX need to configure to skip 8B
47 	 * during packet parsing.
48 	 */
49 
50 	/* CNF10K-B */
51 	if (rvu->mcs_blk_cnt > 1) {
52 		mcs = mcs_get_pdata(rpm_id);
53 		cfg = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION);
54 		if (ena)
55 			cfg |= BIT_ULL(lmac_id);
56 		else
57 			cfg &= ~BIT_ULL(lmac_id);
58 		mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION, cfg);
59 		return;
60 	}
61 	/* CN10KB */
62 	mcs = mcs_get_pdata(0);
63 	port = (rpm_id * rvu->hw->lmac_per_cgx) + lmac_id;
64 	cfg = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PORT_CFGX(port));
65 	if (ena)
66 		cfg |= BIT_ULL(0);
67 	else
68 		cfg &= ~BIT_ULL(0);
69 	mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PORT_CFGX(port), cfg);
70 }
71 
72 int rvu_mbox_handler_mcs_set_lmac_mode(struct rvu *rvu,
73 				       struct mcs_set_lmac_mode *req,
74 				       struct msg_rsp *rsp)
75 {
76 	struct mcs *mcs;
77 
78 	if (req->mcs_id >= rvu->mcs_blk_cnt)
79 		return MCS_AF_ERR_INVALID_MCSID;
80 
81 	mcs = mcs_get_pdata(req->mcs_id);
82 
83 	if (BIT_ULL(req->lmac_id) & mcs->hw->lmac_bmap)
84 		mcs_set_lmac_mode(mcs, req->lmac_id, req->mode);
85 
86 	return 0;
87 }
88 
89 int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event)
90 {
91 	struct mcs_intrq_entry *qentry;
92 	u16 pcifunc = event->pcifunc;
93 	struct rvu *rvu = mcs->rvu;
94 	struct mcs_pfvf *pfvf;
95 
96 	/* Check if it is PF or VF */
97 	if (pcifunc & RVU_PFVF_FUNC_MASK)
98 		pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
99 	else
100 		pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
101 
102 	event->intr_mask &= pfvf->intr_mask;
103 
104 	/* Check PF/VF interrupt notification is enabled */
105 	if (!(pfvf->intr_mask && event->intr_mask))
106 		return 0;
107 
108 	qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC);
109 	if (!qentry)
110 		return -ENOMEM;
111 
112 	qentry->intr_event = *event;
113 	spin_lock(&rvu->mcs_intrq_lock);
114 	list_add_tail(&qentry->node, &rvu->mcs_intrq_head);
115 	spin_unlock(&rvu->mcs_intrq_lock);
116 	queue_work(rvu->mcs_intr_wq, &rvu->mcs_intr_work);
117 
118 	return 0;
119 }
120 
121 static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
122 {
123 	struct mcs_intr_info *req;
124 	int pf;
125 
126 	pf = rvu_get_pf(event->pcifunc);
127 
128 	mutex_lock(&rvu->mbox_lock);
129 
130 	req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf);
131 	if (!req) {
132 		mutex_unlock(&rvu->mbox_lock);
133 		return -ENOMEM;
134 	}
135 
136 	req->mcs_id = event->mcs_id;
137 	req->intr_mask = event->intr_mask;
138 	req->sa_id = event->sa_id;
139 	req->hdr.pcifunc = event->pcifunc;
140 	req->lmac_id = event->lmac_id;
141 
142 	otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
143 
144 	otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
145 
146 	mutex_unlock(&rvu->mbox_lock);
147 
148 	return 0;
149 }
150 
151 static void mcs_intr_handler_task(struct work_struct *work)
152 {
153 	struct rvu *rvu = container_of(work, struct rvu, mcs_intr_work);
154 	struct mcs_intrq_entry *qentry;
155 	struct mcs_intr_event *event;
156 	unsigned long flags;
157 
158 	do {
159 		spin_lock_irqsave(&rvu->mcs_intrq_lock, flags);
160 		qentry = list_first_entry_or_null(&rvu->mcs_intrq_head,
161 						  struct mcs_intrq_entry,
162 						  node);
163 		if (qentry)
164 			list_del(&qentry->node);
165 
166 		spin_unlock_irqrestore(&rvu->mcs_intrq_lock, flags);
167 		if (!qentry)
168 			break; /* nothing more to process */
169 
170 		event = &qentry->intr_event;
171 
172 		mcs_notify_pfvf(event, rvu);
173 		kfree(qentry);
174 	} while (1);
175 }
176 
177 int rvu_mbox_handler_mcs_intr_cfg(struct rvu *rvu,
178 				  struct mcs_intr_cfg *req,
179 				  struct msg_rsp *rsp)
180 {
181 	u16 pcifunc = req->hdr.pcifunc;
182 	struct mcs_pfvf *pfvf;
183 	struct mcs *mcs;
184 
185 	if (req->mcs_id >= rvu->mcs_blk_cnt)
186 		return MCS_AF_ERR_INVALID_MCSID;
187 
188 	mcs = mcs_get_pdata(req->mcs_id);
189 
190 	/* Check if it is PF or VF */
191 	if (pcifunc & RVU_PFVF_FUNC_MASK)
192 		pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
193 	else
194 		pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
195 
196 	mcs->pf_map[0] = pcifunc;
197 	pfvf->intr_mask = req->intr_mask;
198 
199 	return 0;
200 }
201 
202 int rvu_mbox_handler_mcs_get_hw_info(struct rvu *rvu,
203 				     struct msg_req *req,
204 				     struct mcs_hw_info *rsp)
205 {
206 	struct mcs *mcs;
207 
208 	if (!rvu->mcs_blk_cnt)
209 		return MCS_AF_ERR_NOT_MAPPED;
210 
211 	/* MCS resources are same across all blocks */
212 	mcs = mcs_get_pdata(0);
213 	rsp->num_mcs_blks = rvu->mcs_blk_cnt;
214 	rsp->tcam_entries = mcs->hw->tcam_entries;
215 	rsp->secy_entries = mcs->hw->secy_entries;
216 	rsp->sc_entries = mcs->hw->sc_entries;
217 	rsp->sa_entries = mcs->hw->sa_entries;
218 	return 0;
219 }
220 
221 int rvu_mbox_handler_mcs_port_reset(struct rvu *rvu, struct mcs_port_reset_req *req,
222 				    struct msg_rsp *rsp)
223 {
224 	struct mcs *mcs;
225 
226 	if (req->mcs_id >= rvu->mcs_blk_cnt)
227 		return MCS_AF_ERR_INVALID_MCSID;
228 
229 	mcs = mcs_get_pdata(req->mcs_id);
230 
231 	mcs_reset_port(mcs, req->port_id, req->reset);
232 
233 	return 0;
234 }
235 
236 int rvu_mbox_handler_mcs_clear_stats(struct rvu *rvu,
237 				     struct mcs_clear_stats *req,
238 				     struct msg_rsp *rsp)
239 {
240 	u16 pcifunc = req->hdr.pcifunc;
241 	struct mcs *mcs;
242 
243 	if (req->mcs_id >= rvu->mcs_blk_cnt)
244 		return MCS_AF_ERR_INVALID_MCSID;
245 
246 	mcs = mcs_get_pdata(req->mcs_id);
247 
248 	mutex_lock(&mcs->stats_lock);
249 	if (req->all)
250 		mcs_clear_all_stats(mcs, pcifunc, req->dir);
251 	else
252 		mcs_clear_stats(mcs, req->type, req->id, req->dir);
253 
254 	mutex_unlock(&mcs->stats_lock);
255 	return 0;
256 }
257 
258 int rvu_mbox_handler_mcs_get_flowid_stats(struct rvu *rvu,
259 					  struct mcs_stats_req *req,
260 					  struct mcs_flowid_stats *rsp)
261 {
262 	struct mcs *mcs;
263 
264 	if (req->mcs_id >= rvu->mcs_blk_cnt)
265 		return MCS_AF_ERR_INVALID_MCSID;
266 
267 	mcs = mcs_get_pdata(req->mcs_id);
268 
269 	/* In CNF10K-B, before reading the statistics,
270 	 * MCSX_MIL_GLOBAL.FORCE_CLK_EN_IP needs to be set
271 	 * to get accurate statistics
272 	 */
273 	if (mcs->hw->mcs_blks > 1)
274 		mcs_set_force_clk_en(mcs, true);
275 
276 	mutex_lock(&mcs->stats_lock);
277 	mcs_get_flowid_stats(mcs, rsp, req->id, req->dir);
278 	mutex_unlock(&mcs->stats_lock);
279 
280 	/* Clear MCSX_MIL_GLOBAL.FORCE_CLK_EN_IP after reading
281 	 * the statistics
282 	 */
283 	if (mcs->hw->mcs_blks > 1)
284 		mcs_set_force_clk_en(mcs, false);
285 
286 	return 0;
287 }
288 
289 int rvu_mbox_handler_mcs_get_secy_stats(struct rvu *rvu,
290 					struct mcs_stats_req *req,
291 					struct mcs_secy_stats *rsp)
292 {	struct mcs *mcs;
293 
294 	if (req->mcs_id >= rvu->mcs_blk_cnt)
295 		return MCS_AF_ERR_INVALID_MCSID;
296 
297 	mcs = mcs_get_pdata(req->mcs_id);
298 
299 	if (mcs->hw->mcs_blks > 1)
300 		mcs_set_force_clk_en(mcs, true);
301 
302 	mutex_lock(&mcs->stats_lock);
303 
304 	if (req->dir == MCS_RX)
305 		mcs_get_rx_secy_stats(mcs, rsp, req->id);
306 	else
307 		mcs_get_tx_secy_stats(mcs, rsp, req->id);
308 
309 	mutex_unlock(&mcs->stats_lock);
310 
311 	if (mcs->hw->mcs_blks > 1)
312 		mcs_set_force_clk_en(mcs, false);
313 
314 	return 0;
315 }
316 
317 int rvu_mbox_handler_mcs_get_sc_stats(struct rvu *rvu,
318 				      struct mcs_stats_req *req,
319 				      struct mcs_sc_stats *rsp)
320 {
321 	struct mcs *mcs;
322 
323 	if (req->mcs_id >= rvu->mcs_blk_cnt)
324 		return MCS_AF_ERR_INVALID_MCSID;
325 
326 	mcs = mcs_get_pdata(req->mcs_id);
327 
328 	if (mcs->hw->mcs_blks > 1)
329 		mcs_set_force_clk_en(mcs, true);
330 
331 	mutex_lock(&mcs->stats_lock);
332 	mcs_get_sc_stats(mcs, rsp, req->id, req->dir);
333 	mutex_unlock(&mcs->stats_lock);
334 
335 	if (mcs->hw->mcs_blks > 1)
336 		mcs_set_force_clk_en(mcs, false);
337 
338 	return 0;
339 }
340 
341 int rvu_mbox_handler_mcs_get_sa_stats(struct rvu *rvu,
342 				      struct mcs_stats_req *req,
343 				      struct mcs_sa_stats *rsp)
344 {
345 	struct mcs *mcs;
346 
347 	if (req->mcs_id >= rvu->mcs_blk_cnt)
348 		return MCS_AF_ERR_INVALID_MCSID;
349 
350 	mcs = mcs_get_pdata(req->mcs_id);
351 
352 	if (mcs->hw->mcs_blks > 1)
353 		mcs_set_force_clk_en(mcs, true);
354 
355 	mutex_lock(&mcs->stats_lock);
356 	mcs_get_sa_stats(mcs, rsp, req->id, req->dir);
357 	mutex_unlock(&mcs->stats_lock);
358 
359 	if (mcs->hw->mcs_blks > 1)
360 		mcs_set_force_clk_en(mcs, false);
361 
362 	return 0;
363 }
364 
365 int rvu_mbox_handler_mcs_get_port_stats(struct rvu *rvu,
366 					struct mcs_stats_req *req,
367 					struct mcs_port_stats *rsp)
368 {
369 	struct mcs *mcs;
370 
371 	if (req->mcs_id >= rvu->mcs_blk_cnt)
372 		return MCS_AF_ERR_INVALID_MCSID;
373 
374 	mcs = mcs_get_pdata(req->mcs_id);
375 
376 	if (mcs->hw->mcs_blks > 1)
377 		mcs_set_force_clk_en(mcs, true);
378 
379 	mutex_lock(&mcs->stats_lock);
380 	mcs_get_port_stats(mcs, rsp, req->id, req->dir);
381 	mutex_unlock(&mcs->stats_lock);
382 
383 	if (mcs->hw->mcs_blks > 1)
384 		mcs_set_force_clk_en(mcs, false);
385 
386 	return 0;
387 }
388 
389 int rvu_mbox_handler_mcs_set_active_lmac(struct rvu *rvu,
390 					 struct mcs_set_active_lmac *req,
391 					 struct msg_rsp *rsp)
392 {
393 	struct mcs *mcs;
394 
395 	if (req->mcs_id >= rvu->mcs_blk_cnt)
396 		return MCS_AF_ERR_INVALID_MCSID;
397 
398 	mcs = mcs_get_pdata(req->mcs_id);
399 	if (!mcs)
400 		return MCS_AF_ERR_NOT_MAPPED;
401 
402 	mcs->hw->lmac_bmap = req->lmac_bmap;
403 	mcs_set_lmac_channels(req->mcs_id, req->chan_base);
404 	return 0;
405 }
406 
407 int rvu_mbox_handler_mcs_port_cfg_set(struct rvu *rvu, struct mcs_port_cfg_set_req *req,
408 				      struct msg_rsp *rsp)
409 {
410 	struct mcs *mcs;
411 
412 	if (req->mcs_id >= rvu->mcs_blk_cnt)
413 		return MCS_AF_ERR_INVALID_MCSID;
414 
415 	mcs = mcs_get_pdata(req->mcs_id);
416 
417 	if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id)))
418 		return -EINVAL;
419 
420 	mcs_set_port_cfg(mcs, req);
421 
422 	return 0;
423 }
424 
425 int rvu_mbox_handler_mcs_port_cfg_get(struct rvu *rvu, struct mcs_port_cfg_get_req *req,
426 				      struct mcs_port_cfg_get_rsp *rsp)
427 {
428 	struct mcs *mcs;
429 
430 	if (req->mcs_id >= rvu->mcs_blk_cnt)
431 		return MCS_AF_ERR_INVALID_MCSID;
432 
433 	mcs = mcs_get_pdata(req->mcs_id);
434 
435 	if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id)))
436 		return -EINVAL;
437 
438 	mcs_get_port_cfg(mcs, req, rsp);
439 
440 	return 0;
441 }
442 
443 int rvu_mbox_handler_mcs_custom_tag_cfg_get(struct rvu *rvu, struct mcs_custom_tag_cfg_get_req *req,
444 					    struct mcs_custom_tag_cfg_get_rsp *rsp)
445 {
446 	struct mcs *mcs;
447 
448 	if (req->mcs_id >= rvu->mcs_blk_cnt)
449 		return MCS_AF_ERR_INVALID_MCSID;
450 
451 	mcs = mcs_get_pdata(req->mcs_id);
452 
453 	mcs_get_custom_tag_cfg(mcs, req, rsp);
454 
455 	return 0;
456 }
457 
458 int rvu_mcs_flr_handler(struct rvu *rvu, u16 pcifunc)
459 {
460 	struct mcs *mcs;
461 	int mcs_id;
462 
463 	/* CNF10K-B mcs0-6 are mapped to RPM2-8*/
464 	if (rvu->mcs_blk_cnt > 1) {
465 		for (mcs_id = 0; mcs_id < rvu->mcs_blk_cnt; mcs_id++) {
466 			mcs = mcs_get_pdata(mcs_id);
467 			mcs_free_all_rsrc(mcs, MCS_RX, pcifunc);
468 			mcs_free_all_rsrc(mcs, MCS_TX, pcifunc);
469 		}
470 	} else {
471 		/* CN10K-B has only one mcs block */
472 		mcs = mcs_get_pdata(0);
473 		mcs_free_all_rsrc(mcs, MCS_RX, pcifunc);
474 		mcs_free_all_rsrc(mcs, MCS_TX, pcifunc);
475 	}
476 	return 0;
477 }
478 
479 int rvu_mbox_handler_mcs_flowid_ena_entry(struct rvu *rvu,
480 					  struct mcs_flowid_ena_dis_entry *req,
481 					  struct msg_rsp *rsp)
482 {
483 	struct mcs *mcs;
484 
485 	if (req->mcs_id >= rvu->mcs_blk_cnt)
486 		return MCS_AF_ERR_INVALID_MCSID;
487 
488 	mcs = mcs_get_pdata(req->mcs_id);
489 	mcs_ena_dis_flowid_entry(mcs, req->flow_id, req->dir, req->ena);
490 	return 0;
491 }
492 
493 int rvu_mbox_handler_mcs_pn_table_write(struct rvu *rvu,
494 					struct mcs_pn_table_write_req *req,
495 					struct msg_rsp *rsp)
496 {
497 	struct mcs *mcs;
498 
499 	if (req->mcs_id >= rvu->mcs_blk_cnt)
500 		return MCS_AF_ERR_INVALID_MCSID;
501 
502 	mcs = mcs_get_pdata(req->mcs_id);
503 	mcs_pn_table_write(mcs, req->pn_id, req->next_pn, req->dir);
504 	return 0;
505 }
506 
507 int rvu_mbox_handler_mcs_set_pn_threshold(struct rvu *rvu,
508 					  struct mcs_set_pn_threshold *req,
509 					  struct msg_rsp *rsp)
510 {
511 	struct mcs *mcs;
512 
513 	if (req->mcs_id >= rvu->mcs_blk_cnt)
514 		return MCS_AF_ERR_INVALID_MCSID;
515 
516 	mcs = mcs_get_pdata(req->mcs_id);
517 
518 	mcs_pn_threshold_set(mcs, req);
519 
520 	return 0;
521 }
522 
523 int rvu_mbox_handler_mcs_rx_sc_sa_map_write(struct rvu *rvu,
524 					    struct mcs_rx_sc_sa_map *req,
525 					    struct msg_rsp *rsp)
526 {
527 	struct mcs *mcs;
528 
529 	if (req->mcs_id >= rvu->mcs_blk_cnt)
530 		return MCS_AF_ERR_INVALID_MCSID;
531 
532 	mcs = mcs_get_pdata(req->mcs_id);
533 	mcs->mcs_ops->mcs_rx_sa_mem_map_write(mcs, req);
534 	return 0;
535 }
536 
537 int rvu_mbox_handler_mcs_tx_sc_sa_map_write(struct rvu *rvu,
538 					    struct mcs_tx_sc_sa_map *req,
539 					    struct msg_rsp *rsp)
540 {
541 	struct mcs *mcs;
542 
543 	if (req->mcs_id >= rvu->mcs_blk_cnt)
544 		return MCS_AF_ERR_INVALID_MCSID;
545 
546 	mcs = mcs_get_pdata(req->mcs_id);
547 	mcs->mcs_ops->mcs_tx_sa_mem_map_write(mcs, req);
548 	mcs->tx_sa_active[req->sc_id] = req->tx_sa_active;
549 
550 	return 0;
551 }
552 
553 int rvu_mbox_handler_mcs_sa_plcy_write(struct rvu *rvu,
554 				       struct mcs_sa_plcy_write_req *req,
555 				       struct msg_rsp *rsp)
556 {
557 	struct mcs *mcs;
558 	int i;
559 
560 	if (req->mcs_id >= rvu->mcs_blk_cnt)
561 		return MCS_AF_ERR_INVALID_MCSID;
562 
563 	mcs = mcs_get_pdata(req->mcs_id);
564 
565 	for (i = 0; i < req->sa_cnt; i++)
566 		mcs_sa_plcy_write(mcs, &req->plcy[i][0],
567 				  req->sa_index[i], req->dir);
568 	return 0;
569 }
570 
571 int rvu_mbox_handler_mcs_rx_sc_cam_write(struct rvu *rvu,
572 					 struct mcs_rx_sc_cam_write_req *req,
573 					 struct msg_rsp *rsp)
574 {
575 	struct mcs *mcs;
576 
577 	if (req->mcs_id >= rvu->mcs_blk_cnt)
578 		return MCS_AF_ERR_INVALID_MCSID;
579 
580 	mcs = mcs_get_pdata(req->mcs_id);
581 	mcs_rx_sc_cam_write(mcs, req->sci, req->secy_id, req->sc_id);
582 	return 0;
583 }
584 
585 int rvu_mbox_handler_mcs_secy_plcy_write(struct rvu *rvu,
586 					 struct mcs_secy_plcy_write_req *req,
587 					 struct msg_rsp *rsp)
588 {	struct mcs *mcs;
589 
590 	if (req->mcs_id >= rvu->mcs_blk_cnt)
591 		return MCS_AF_ERR_INVALID_MCSID;
592 
593 	mcs = mcs_get_pdata(req->mcs_id);
594 
595 	mcs_secy_plcy_write(mcs, req->plcy,
596 			    req->secy_id, req->dir);
597 	return 0;
598 }
599 
600 int rvu_mbox_handler_mcs_flowid_entry_write(struct rvu *rvu,
601 					    struct mcs_flowid_entry_write_req *req,
602 					    struct msg_rsp *rsp)
603 {
604 	struct secy_mem_map map;
605 	struct mcs *mcs;
606 
607 	if (req->mcs_id >= rvu->mcs_blk_cnt)
608 		return MCS_AF_ERR_INVALID_MCSID;
609 
610 	mcs = mcs_get_pdata(req->mcs_id);
611 
612 	/* TODO validate the flowid */
613 	mcs_flowid_entry_write(mcs, req->data, req->mask,
614 			       req->flow_id, req->dir);
615 	map.secy = req->secy_id;
616 	map.sc = req->sc_id;
617 	map.ctrl_pkt = req->ctrl_pkt;
618 	map.flow_id = req->flow_id;
619 	map.sci = req->sci;
620 	mcs->mcs_ops->mcs_flowid_secy_map(mcs, &map, req->dir);
621 	if (req->ena)
622 		mcs_ena_dis_flowid_entry(mcs, req->flow_id,
623 					 req->dir, true);
624 	return 0;
625 }
626 
627 int rvu_mbox_handler_mcs_free_resources(struct rvu *rvu,
628 					struct mcs_free_rsrc_req *req,
629 					struct msg_rsp *rsp)
630 {
631 	u16 pcifunc = req->hdr.pcifunc;
632 	struct mcs_rsrc_map *map;
633 	struct mcs *mcs;
634 	int rc = 0;
635 
636 	if (req->mcs_id >= rvu->mcs_blk_cnt)
637 		return MCS_AF_ERR_INVALID_MCSID;
638 
639 	mcs = mcs_get_pdata(req->mcs_id);
640 
641 	if (req->dir == MCS_RX)
642 		map = &mcs->rx;
643 	else
644 		map = &mcs->tx;
645 
646 	mutex_lock(&rvu->rsrc_lock);
647 	/* Free all the cam resources mapped to PF/VF */
648 	if (req->all) {
649 		rc = mcs_free_all_rsrc(mcs, req->dir, pcifunc);
650 		goto exit;
651 	}
652 
653 	switch (req->rsrc_type) {
654 	case MCS_RSRC_TYPE_FLOWID:
655 		rc = mcs_free_rsrc(&map->flow_ids, map->flowid2pf_map, req->rsrc_id, pcifunc);
656 		mcs_ena_dis_flowid_entry(mcs, req->rsrc_id, req->dir, false);
657 		break;
658 	case MCS_RSRC_TYPE_SECY:
659 		rc =  mcs_free_rsrc(&map->secy, map->secy2pf_map, req->rsrc_id, pcifunc);
660 		mcs_clear_secy_plcy(mcs, req->rsrc_id, req->dir);
661 		break;
662 	case MCS_RSRC_TYPE_SC:
663 		rc = mcs_free_rsrc(&map->sc, map->sc2pf_map, req->rsrc_id, pcifunc);
664 		/* Disable SC CAM only on RX side */
665 		if (req->dir == MCS_RX)
666 			mcs_ena_dis_sc_cam_entry(mcs, req->rsrc_id, false);
667 		break;
668 	case MCS_RSRC_TYPE_SA:
669 		rc = mcs_free_rsrc(&map->sa, map->sa2pf_map, req->rsrc_id, pcifunc);
670 		break;
671 	}
672 exit:
673 	mutex_unlock(&rvu->rsrc_lock);
674 	return rc;
675 }
676 
677 int rvu_mbox_handler_mcs_alloc_resources(struct rvu *rvu,
678 					 struct mcs_alloc_rsrc_req *req,
679 					 struct mcs_alloc_rsrc_rsp *rsp)
680 {
681 	u16 pcifunc = req->hdr.pcifunc;
682 	struct mcs_rsrc_map *map;
683 	struct mcs *mcs;
684 	int rsrc_id, i;
685 
686 	if (req->mcs_id >= rvu->mcs_blk_cnt)
687 		return MCS_AF_ERR_INVALID_MCSID;
688 
689 	mcs = mcs_get_pdata(req->mcs_id);
690 
691 	if (req->dir == MCS_RX)
692 		map = &mcs->rx;
693 	else
694 		map = &mcs->tx;
695 
696 	mutex_lock(&rvu->rsrc_lock);
697 
698 	if (req->all) {
699 		rsrc_id = mcs_alloc_all_rsrc(mcs, &rsp->flow_ids[0],
700 					     &rsp->secy_ids[0],
701 					     &rsp->sc_ids[0],
702 					     &rsp->sa_ids[0],
703 					     &rsp->sa_ids[1],
704 					     pcifunc, req->dir);
705 		goto exit;
706 	}
707 
708 	switch (req->rsrc_type) {
709 	case MCS_RSRC_TYPE_FLOWID:
710 		for (i = 0; i < req->rsrc_cnt; i++) {
711 			rsrc_id = mcs_alloc_rsrc(&map->flow_ids, map->flowid2pf_map, pcifunc);
712 			if (rsrc_id < 0)
713 				goto exit;
714 			rsp->flow_ids[i] = rsrc_id;
715 			rsp->rsrc_cnt++;
716 		}
717 		break;
718 	case MCS_RSRC_TYPE_SECY:
719 		for (i = 0; i < req->rsrc_cnt; i++) {
720 			rsrc_id = mcs_alloc_rsrc(&map->secy, map->secy2pf_map, pcifunc);
721 			if (rsrc_id < 0)
722 				goto exit;
723 			rsp->secy_ids[i] = rsrc_id;
724 			rsp->rsrc_cnt++;
725 		}
726 		break;
727 	case MCS_RSRC_TYPE_SC:
728 		for (i = 0; i < req->rsrc_cnt; i++) {
729 			rsrc_id = mcs_alloc_rsrc(&map->sc, map->sc2pf_map, pcifunc);
730 			if (rsrc_id < 0)
731 				goto exit;
732 			rsp->sc_ids[i] = rsrc_id;
733 			rsp->rsrc_cnt++;
734 		}
735 		break;
736 	case MCS_RSRC_TYPE_SA:
737 		for (i = 0; i < req->rsrc_cnt; i++) {
738 			rsrc_id = mcs_alloc_rsrc(&map->sa, map->sa2pf_map, pcifunc);
739 			if (rsrc_id < 0)
740 				goto exit;
741 			rsp->sa_ids[i] = rsrc_id;
742 			rsp->rsrc_cnt++;
743 		}
744 		break;
745 	}
746 
747 	rsp->rsrc_type = req->rsrc_type;
748 	rsp->dir = req->dir;
749 	rsp->mcs_id = req->mcs_id;
750 	rsp->all = req->all;
751 
752 exit:
753 	if (rsrc_id < 0)
754 		dev_err(rvu->dev, "Failed to allocate the mcs resources for PCIFUNC:%d\n", pcifunc);
755 	mutex_unlock(&rvu->rsrc_lock);
756 	return 0;
757 }
758 
759 int rvu_mbox_handler_mcs_alloc_ctrl_pkt_rule(struct rvu *rvu,
760 					     struct mcs_alloc_ctrl_pkt_rule_req *req,
761 					     struct mcs_alloc_ctrl_pkt_rule_rsp *rsp)
762 {
763 	u16 pcifunc = req->hdr.pcifunc;
764 	struct mcs_rsrc_map *map;
765 	struct mcs *mcs;
766 	int rsrc_id;
767 	u16 offset;
768 
769 	if (req->mcs_id >= rvu->mcs_blk_cnt)
770 		return MCS_AF_ERR_INVALID_MCSID;
771 
772 	mcs = mcs_get_pdata(req->mcs_id);
773 
774 	map = (req->dir == MCS_RX) ? &mcs->rx : &mcs->tx;
775 
776 	mutex_lock(&rvu->rsrc_lock);
777 
778 	switch (req->rule_type) {
779 	case MCS_CTRL_PKT_RULE_TYPE_ETH:
780 		offset = MCS_CTRLPKT_ETYPE_RULE_OFFSET;
781 		break;
782 	case MCS_CTRL_PKT_RULE_TYPE_DA:
783 		offset = MCS_CTRLPKT_DA_RULE_OFFSET;
784 		break;
785 	case MCS_CTRL_PKT_RULE_TYPE_RANGE:
786 		offset = MCS_CTRLPKT_DA_RANGE_RULE_OFFSET;
787 		break;
788 	case MCS_CTRL_PKT_RULE_TYPE_COMBO:
789 		offset = MCS_CTRLPKT_COMBO_RULE_OFFSET;
790 		break;
791 	case MCS_CTRL_PKT_RULE_TYPE_MAC:
792 		offset = MCS_CTRLPKT_MAC_EN_RULE_OFFSET;
793 		break;
794 	}
795 
796 	rsrc_id = mcs_alloc_ctrlpktrule(&map->ctrlpktrule, map->ctrlpktrule2pf_map, offset,
797 					pcifunc);
798 	if (rsrc_id < 0)
799 		goto exit;
800 
801 	rsp->rule_idx = rsrc_id;
802 	rsp->rule_type = req->rule_type;
803 	rsp->dir = req->dir;
804 	rsp->mcs_id = req->mcs_id;
805 
806 	mutex_unlock(&rvu->rsrc_lock);
807 	return 0;
808 exit:
809 	if (rsrc_id < 0)
810 		dev_err(rvu->dev, "Failed to allocate the mcs ctrl pkt rule for PCIFUNC:%d\n",
811 			pcifunc);
812 	mutex_unlock(&rvu->rsrc_lock);
813 	return rsrc_id;
814 }
815 
816 int rvu_mbox_handler_mcs_free_ctrl_pkt_rule(struct rvu *rvu,
817 					    struct mcs_free_ctrl_pkt_rule_req *req,
818 					    struct msg_rsp *rsp)
819 {
820 	struct mcs *mcs;
821 	int rc;
822 
823 	if (req->mcs_id >= rvu->mcs_blk_cnt)
824 		return MCS_AF_ERR_INVALID_MCSID;
825 
826 	mcs = mcs_get_pdata(req->mcs_id);
827 
828 	mutex_lock(&rvu->rsrc_lock);
829 
830 	rc = mcs_free_ctrlpktrule(mcs, req);
831 
832 	mutex_unlock(&rvu->rsrc_lock);
833 
834 	return rc;
835 }
836 
837 int rvu_mbox_handler_mcs_ctrl_pkt_rule_write(struct rvu *rvu,
838 					     struct mcs_ctrl_pkt_rule_write_req *req,
839 					     struct msg_rsp *rsp)
840 {
841 	struct mcs *mcs;
842 	int rc;
843 
844 	if (req->mcs_id >= rvu->mcs_blk_cnt)
845 		return MCS_AF_ERR_INVALID_MCSID;
846 
847 	mcs = mcs_get_pdata(req->mcs_id);
848 
849 	rc = mcs_ctrlpktrule_write(mcs, req);
850 
851 	return rc;
852 }
853 
854 static void rvu_mcs_set_lmac_bmap(struct rvu *rvu)
855 {
856 	struct mcs *mcs = mcs_get_pdata(0);
857 	unsigned long lmac_bmap;
858 	int cgx, lmac, port;
859 
860 	for (port = 0; port < mcs->hw->lmac_cnt; port++) {
861 		cgx = port / rvu->hw->lmac_per_cgx;
862 		lmac = port % rvu->hw->lmac_per_cgx;
863 		if (!is_lmac_valid(rvu_cgx_pdata(cgx, rvu), lmac))
864 			continue;
865 		set_bit(port, &lmac_bmap);
866 	}
867 	mcs->hw->lmac_bmap = lmac_bmap;
868 }
869 
870 int rvu_mcs_init(struct rvu *rvu)
871 {
872 	struct rvu_hwinfo *hw = rvu->hw;
873 	int lmac, err = 0, mcs_id;
874 	struct mcs *mcs;
875 
876 	rvu->mcs_blk_cnt = mcs_get_blkcnt();
877 
878 	if (!rvu->mcs_blk_cnt)
879 		return 0;
880 
881 	/* Needed only for CN10K-B */
882 	if (rvu->mcs_blk_cnt == 1) {
883 		err = mcs_set_lmac_channels(0, hw->cgx_chan_base);
884 		if (err)
885 			return err;
886 		/* Set active lmacs */
887 		rvu_mcs_set_lmac_bmap(rvu);
888 	}
889 
890 	/* Install default tcam bypass entry and set port to operational mode */
891 	for (mcs_id = 0; mcs_id < rvu->mcs_blk_cnt; mcs_id++) {
892 		mcs = mcs_get_pdata(mcs_id);
893 		mcs_install_flowid_bypass_entry(mcs);
894 		for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++)
895 			mcs_set_lmac_mode(mcs, lmac, 0);
896 
897 		mcs->rvu = rvu;
898 
899 		/* Allocated memory for PFVF data */
900 		mcs->pf = devm_kcalloc(mcs->dev, hw->total_pfs,
901 				       sizeof(struct mcs_pfvf), GFP_KERNEL);
902 		if (!mcs->pf)
903 			return -ENOMEM;
904 
905 		mcs->vf = devm_kcalloc(mcs->dev, hw->total_vfs,
906 				       sizeof(struct mcs_pfvf), GFP_KERNEL);
907 		if (!mcs->vf)
908 			return -ENOMEM;
909 	}
910 
911 	/* Initialize the wq for handling mcs interrupts */
912 	INIT_LIST_HEAD(&rvu->mcs_intrq_head);
913 	INIT_WORK(&rvu->mcs_intr_work, mcs_intr_handler_task);
914 	rvu->mcs_intr_wq = alloc_workqueue("mcs_intr_wq", 0, 0);
915 	if (!rvu->mcs_intr_wq) {
916 		dev_err(rvu->dev, "mcs alloc workqueue failed\n");
917 		return -ENOMEM;
918 	}
919 
920 	return err;
921 }
922 
923 void rvu_mcs_exit(struct rvu *rvu)
924 {
925 	if (!rvu->mcs_intr_wq)
926 		return;
927 
928 	flush_workqueue(rvu->mcs_intr_wq);
929 	destroy_workqueue(rvu->mcs_intr_wq);
930 	rvu->mcs_intr_wq = NULL;
931 }
932