brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · d39d86e Raw
932 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Marvell CN10K MCS driver3 *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)			\18static 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 33MBOX_UP_MCS_MESSAGES34#undef M35 36void 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 all46	 * RX packets. MCS PEX need to configure to skip 8B47	 * 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		else57			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	else68		cfg &= ~BIT_ULL(0);69	mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PORT_CFGX(port), cfg);70}71 72int 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 89int 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	else100		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 121static 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 151static 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 177int 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	else194		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 202int 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 221int 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 236int 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	else252		mcs_clear_stats(mcs, req->type, req->id, req->dir);253 254	mutex_unlock(&mcs->stats_lock);255	return 0;256}257 258int 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 set271	 * to get accurate statistics272	 */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 reading281	 * the statistics282	 */283	if (mcs->hw->mcs_blks > 1)284		mcs_set_force_clk_en(mcs, false);285 286	return 0;287}288 289int 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	else307		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 317int 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 341int 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 365int 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 389int 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 407int 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 425int 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 443int 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 458int 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 479int 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 493int 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 507int 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 523int 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 537int 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 553int 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 571int 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 585int 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 600int 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 627int 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	else644		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	}672exit:673	mutex_unlock(&rvu->rsrc_lock);674	return rc;675}676 677int 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	else694		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 752exit: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 759int 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;808exit: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 816int 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 837int 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 854static 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 870int 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 923void 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