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