brintos

brintos / linux-shallow public Read only

0
0
Text · 44.0 KiB · 6cc7a78 Raw
1817 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Marvell MACSEC hardware offload driver3 *4 * Copyright (C) 2022 Marvell.5 */6 7#include <crypto/skcipher.h>8#include <linux/rtnetlink.h>9#include <linux/bitfield.h>10#include "otx2_common.h"11 12#define MCS_TCAM0_MAC_DA_MASK		GENMASK_ULL(47, 0)13#define MCS_TCAM0_MAC_SA_MASK		GENMASK_ULL(63, 48)14#define MCS_TCAM1_MAC_SA_MASK		GENMASK_ULL(31, 0)15#define MCS_TCAM1_ETYPE_MASK		GENMASK_ULL(47, 32)16 17#define MCS_SA_MAP_MEM_SA_USE		BIT_ULL(9)18 19#define MCS_RX_SECY_PLCY_RW_MASK	GENMASK_ULL(49, 18)20#define MCS_RX_SECY_PLCY_RP		BIT_ULL(17)21#define MCS_RX_SECY_PLCY_AUTH_ENA	BIT_ULL(16)22#define MCS_RX_SECY_PLCY_CIP		GENMASK_ULL(8, 5)23#define MCS_RX_SECY_PLCY_VAL		GENMASK_ULL(2, 1)24#define MCS_RX_SECY_PLCY_ENA		BIT_ULL(0)25 26#define MCS_TX_SECY_PLCY_MTU		GENMASK_ULL(43, 28)27#define MCS_TX_SECY_PLCY_ST_TCI		GENMASK_ULL(27, 22)28#define MCS_TX_SECY_PLCY_ST_OFFSET	GENMASK_ULL(21, 15)29#define MCS_TX_SECY_PLCY_INS_MODE	BIT_ULL(14)30#define MCS_TX_SECY_PLCY_AUTH_ENA	BIT_ULL(13)31#define MCS_TX_SECY_PLCY_CIP		GENMASK_ULL(5, 2)32#define MCS_TX_SECY_PLCY_PROTECT	BIT_ULL(1)33#define MCS_TX_SECY_PLCY_ENA		BIT_ULL(0)34 35#define MCS_GCM_AES_128			036#define MCS_GCM_AES_256			137#define MCS_GCM_AES_XPN_128		238#define MCS_GCM_AES_XPN_256		339 40#define MCS_TCI_ES			0x40 /* end station */41#define MCS_TCI_SC			0x20 /* SCI present */42#define MCS_TCI_SCB			0x10 /* epon */43#define MCS_TCI_E			0x08 /* encryption */44#define MCS_TCI_C			0x04 /* changed text */45 46#define CN10K_MAX_HASH_LEN		1647#define CN10K_MAX_SAK_LEN		3248 49static int cn10k_ecb_aes_encrypt(struct otx2_nic *pfvf, u8 *sak,50				 u16 sak_len, u8 *hash)51{52	u8 data[CN10K_MAX_HASH_LEN] = { 0 };53	struct skcipher_request *req = NULL;54	struct scatterlist sg_src, sg_dst;55	struct crypto_skcipher *tfm;56	DECLARE_CRYPTO_WAIT(wait);57	int err;58 59	tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);60	if (IS_ERR(tfm)) {61		dev_err(pfvf->dev, "failed to allocate transform for ecb-aes\n");62		return PTR_ERR(tfm);63	}64 65	req = skcipher_request_alloc(tfm, GFP_KERNEL);66	if (!req) {67		dev_err(pfvf->dev, "failed to allocate request for skcipher\n");68		err = -ENOMEM;69		goto free_tfm;70	}71 72	err = crypto_skcipher_setkey(tfm, sak, sak_len);73	if (err) {74		dev_err(pfvf->dev, "failed to set key for skcipher\n");75		goto free_req;76	}77 78	/* build sg list */79	sg_init_one(&sg_src, data, CN10K_MAX_HASH_LEN);80	sg_init_one(&sg_dst, hash, CN10K_MAX_HASH_LEN);81 82	skcipher_request_set_callback(req, 0, crypto_req_done, &wait);83	skcipher_request_set_crypt(req, &sg_src, &sg_dst,84				   CN10K_MAX_HASH_LEN, NULL);85 86	err = crypto_skcipher_encrypt(req);87	err = crypto_wait_req(err, &wait);88 89free_req:90	skcipher_request_free(req);91free_tfm:92	crypto_free_skcipher(tfm);93	return err;94}95 96static struct cn10k_mcs_txsc *cn10k_mcs_get_txsc(struct cn10k_mcs_cfg *cfg,97						 struct macsec_secy *secy)98{99	struct cn10k_mcs_txsc *txsc;100 101	list_for_each_entry(txsc, &cfg->txsc_list, entry) {102		if (txsc->sw_secy == secy)103			return txsc;104	}105 106	return NULL;107}108 109static struct cn10k_mcs_rxsc *cn10k_mcs_get_rxsc(struct cn10k_mcs_cfg *cfg,110						 struct macsec_secy *secy,111						 struct macsec_rx_sc *rx_sc)112{113	struct cn10k_mcs_rxsc *rxsc;114 115	list_for_each_entry(rxsc, &cfg->rxsc_list, entry) {116		if (rxsc->sw_rxsc == rx_sc && rxsc->sw_secy == secy)117			return rxsc;118	}119 120	return NULL;121}122 123static const char *rsrc_name(enum mcs_rsrc_type rsrc_type)124{125	switch (rsrc_type) {126	case MCS_RSRC_TYPE_FLOWID:127		return "FLOW";128	case MCS_RSRC_TYPE_SC:129		return "SC";130	case MCS_RSRC_TYPE_SECY:131		return "SECY";132	case MCS_RSRC_TYPE_SA:133		return "SA";134	default:135		return "Unknown";136	};137 138	return "Unknown";139}140 141static int cn10k_mcs_alloc_rsrc(struct otx2_nic *pfvf, enum mcs_direction dir,142				enum mcs_rsrc_type type, u16 *rsrc_id)143{144	struct mbox *mbox = &pfvf->mbox;145	struct mcs_alloc_rsrc_req *req;146	struct mcs_alloc_rsrc_rsp *rsp;147	int ret = -ENOMEM;148 149	mutex_lock(&mbox->lock);150 151	req = otx2_mbox_alloc_msg_mcs_alloc_resources(mbox);152	if (!req)153		goto fail;154 155	req->rsrc_type = type;156	req->rsrc_cnt  = 1;157	req->dir = dir;158 159	ret = otx2_sync_mbox_msg(mbox);160	if (ret)161		goto fail;162 163	rsp = (struct mcs_alloc_rsrc_rsp *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,164							     0, &req->hdr);165	if (IS_ERR(rsp) || req->rsrc_cnt != rsp->rsrc_cnt ||166	    req->rsrc_type != rsp->rsrc_type || req->dir != rsp->dir) {167		ret = -EINVAL;168		goto fail;169	}170 171	switch (rsp->rsrc_type) {172	case MCS_RSRC_TYPE_FLOWID:173		*rsrc_id = rsp->flow_ids[0];174		break;175	case MCS_RSRC_TYPE_SC:176		*rsrc_id = rsp->sc_ids[0];177		break;178	case MCS_RSRC_TYPE_SECY:179		*rsrc_id = rsp->secy_ids[0];180		break;181	case MCS_RSRC_TYPE_SA:182		*rsrc_id = rsp->sa_ids[0];183		break;184	default:185		ret = -EINVAL;186		goto fail;187	}188 189	mutex_unlock(&mbox->lock);190 191	return 0;192fail:193	dev_err(pfvf->dev, "Failed to allocate %s %s resource\n",194		dir == MCS_TX ? "TX" : "RX", rsrc_name(type));195	mutex_unlock(&mbox->lock);196	return ret;197}198 199static void cn10k_mcs_free_rsrc(struct otx2_nic *pfvf, enum mcs_direction dir,200				enum mcs_rsrc_type type, u16 hw_rsrc_id,201				bool all)202{203	struct mcs_clear_stats *clear_req;204	struct mbox *mbox = &pfvf->mbox;205	struct mcs_free_rsrc_req *req;206 207	mutex_lock(&mbox->lock);208 209	clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);210	if (!clear_req)211		goto fail;212 213	clear_req->id = hw_rsrc_id;214	clear_req->type = type;215	clear_req->dir = dir;216 217	req = otx2_mbox_alloc_msg_mcs_free_resources(mbox);218	if (!req)219		goto fail;220 221	req->rsrc_id = hw_rsrc_id;222	req->rsrc_type = type;223	req->dir = dir;224	if (all)225		req->all = 1;226 227	if (otx2_sync_mbox_msg(&pfvf->mbox))228		goto fail;229 230	mutex_unlock(&mbox->lock);231 232	return;233fail:234	dev_err(pfvf->dev, "Failed to free %s %s resource\n",235		dir == MCS_TX ? "TX" : "RX", rsrc_name(type));236	mutex_unlock(&mbox->lock);237}238 239static int cn10k_mcs_alloc_txsa(struct otx2_nic *pfvf, u16 *hw_sa_id)240{241	return cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SA, hw_sa_id);242}243 244static int cn10k_mcs_alloc_rxsa(struct otx2_nic *pfvf, u16 *hw_sa_id)245{246	return cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SA, hw_sa_id);247}248 249static void cn10k_mcs_free_txsa(struct otx2_nic *pfvf, u16 hw_sa_id)250{251	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SA, hw_sa_id, false);252}253 254static void cn10k_mcs_free_rxsa(struct otx2_nic *pfvf, u16 hw_sa_id)255{256	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SA, hw_sa_id, false);257}258 259static int cn10k_mcs_write_rx_secy(struct otx2_nic *pfvf,260				   struct macsec_secy *secy, u8 hw_secy_id)261{262	struct mcs_secy_plcy_write_req *req;263	struct mbox *mbox = &pfvf->mbox;264	u64 policy;265	u8 cipher;266	int ret;267 268	mutex_lock(&mbox->lock);269 270	req = otx2_mbox_alloc_msg_mcs_secy_plcy_write(mbox);271	if (!req) {272		ret = -ENOMEM;273		goto fail;274	}275 276	policy = FIELD_PREP(MCS_RX_SECY_PLCY_RW_MASK, secy->replay_window);277	if (secy->replay_protect)278		policy |= MCS_RX_SECY_PLCY_RP;279 280	policy |= MCS_RX_SECY_PLCY_AUTH_ENA;281 282	switch (secy->key_len) {283	case 16:284		cipher = secy->xpn ? MCS_GCM_AES_XPN_128 : MCS_GCM_AES_128;285		break;286	case 32:287		cipher = secy->xpn ? MCS_GCM_AES_XPN_256 : MCS_GCM_AES_256;288		break;289	default:290		cipher = MCS_GCM_AES_128;291		dev_warn(pfvf->dev, "Unsupported key length\n");292		break;293	}294 295	policy |= FIELD_PREP(MCS_RX_SECY_PLCY_CIP, cipher);296	policy |= FIELD_PREP(MCS_RX_SECY_PLCY_VAL, secy->validate_frames);297 298	policy |= MCS_RX_SECY_PLCY_ENA;299 300	req->plcy = policy;301	req->secy_id = hw_secy_id;302	req->dir = MCS_RX;303 304	ret = otx2_sync_mbox_msg(mbox);305 306fail:307	mutex_unlock(&mbox->lock);308	return ret;309}310 311static int cn10k_mcs_write_rx_flowid(struct otx2_nic *pfvf,312				     struct cn10k_mcs_rxsc *rxsc, u8 hw_secy_id)313{314	struct macsec_rx_sc *sw_rx_sc = rxsc->sw_rxsc;315	struct macsec_secy *secy = rxsc->sw_secy;316	struct mcs_flowid_entry_write_req *req;317	struct mbox *mbox = &pfvf->mbox;318	u64 mac_da;319	int ret;320 321	mutex_lock(&mbox->lock);322 323	req = otx2_mbox_alloc_msg_mcs_flowid_entry_write(mbox);324	if (!req) {325		ret = -ENOMEM;326		goto fail;327	}328 329	mac_da = ether_addr_to_u64(secy->netdev->dev_addr);330 331	req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_DA_MASK, mac_da);332	req->mask[0] = ~0ULL;333	req->mask[0] = ~MCS_TCAM0_MAC_DA_MASK;334 335	req->data[1] = FIELD_PREP(MCS_TCAM1_ETYPE_MASK, ETH_P_MACSEC);336	req->mask[1] = ~0ULL;337	req->mask[1] &= ~MCS_TCAM1_ETYPE_MASK;338 339	req->mask[2] = ~0ULL;340	req->mask[3] = ~0ULL;341 342	req->flow_id = rxsc->hw_flow_id;343	req->secy_id = hw_secy_id;344	req->sc_id = rxsc->hw_sc_id;345	req->dir = MCS_RX;346 347	if (sw_rx_sc->active)348		req->ena = 1;349 350	ret = otx2_sync_mbox_msg(mbox);351 352fail:353	mutex_unlock(&mbox->lock);354	return ret;355}356 357static int cn10k_mcs_write_sc_cam(struct otx2_nic *pfvf,358				  struct cn10k_mcs_rxsc *rxsc, u8 hw_secy_id)359{360	struct macsec_rx_sc *sw_rx_sc = rxsc->sw_rxsc;361	struct mcs_rx_sc_cam_write_req *sc_req;362	struct mbox *mbox = &pfvf->mbox;363	int ret;364 365	mutex_lock(&mbox->lock);366 367	sc_req = otx2_mbox_alloc_msg_mcs_rx_sc_cam_write(mbox);368	if (!sc_req) {369		ret = -ENOMEM;370		goto fail;371	}372 373	sc_req->sci = (__force u64)cpu_to_be64((__force u64)sw_rx_sc->sci);374	sc_req->sc_id = rxsc->hw_sc_id;375	sc_req->secy_id = hw_secy_id;376 377	ret = otx2_sync_mbox_msg(mbox);378 379fail:380	mutex_unlock(&mbox->lock);381	return ret;382}383 384static int cn10k_mcs_write_keys(struct otx2_nic *pfvf,385				struct macsec_secy *secy,386				struct mcs_sa_plcy_write_req *req,387				u8 *sak, u8 *salt, ssci_t ssci)388{389	u8 hash_rev[CN10K_MAX_HASH_LEN];390	u8 sak_rev[CN10K_MAX_SAK_LEN];391	u8 salt_rev[MACSEC_SALT_LEN];392	u8 hash[CN10K_MAX_HASH_LEN];393	u32 ssci_63_32;394	int err, i;395 396	err = cn10k_ecb_aes_encrypt(pfvf, sak, secy->key_len, hash);397	if (err) {398		dev_err(pfvf->dev, "Generating hash using ECB(AES) failed\n");399		return err;400	}401 402	for (i = 0; i < secy->key_len; i++)403		sak_rev[i] = sak[secy->key_len - 1 - i];404 405	for (i = 0; i < CN10K_MAX_HASH_LEN; i++)406		hash_rev[i] = hash[CN10K_MAX_HASH_LEN - 1 - i];407 408	for (i = 0; i < MACSEC_SALT_LEN; i++)409		salt_rev[i] = salt[MACSEC_SALT_LEN - 1 - i];410 411	ssci_63_32 = (__force u32)cpu_to_be32((__force u32)ssci);412 413	memcpy(&req->plcy[0][0], sak_rev, secy->key_len);414	memcpy(&req->plcy[0][4], hash_rev, CN10K_MAX_HASH_LEN);415	memcpy(&req->plcy[0][6], salt_rev, MACSEC_SALT_LEN);416	req->plcy[0][7] |= (u64)ssci_63_32 << 32;417 418	return 0;419}420 421static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf,422				      struct macsec_secy *secy,423				      struct cn10k_mcs_rxsc *rxsc,424				      u8 assoc_num, bool sa_in_use)425{426	struct mcs_sa_plcy_write_req *plcy_req;427	u8 *sak = rxsc->sa_key[assoc_num];428	u8 *salt = rxsc->salt[assoc_num];429	struct mcs_rx_sc_sa_map *map_req;430	struct mbox *mbox = &pfvf->mbox;431	int ret;432 433	mutex_lock(&mbox->lock);434 435	plcy_req = otx2_mbox_alloc_msg_mcs_sa_plcy_write(mbox);436	if (!plcy_req) {437		ret = -ENOMEM;438		goto fail;439	}440 441	map_req = otx2_mbox_alloc_msg_mcs_rx_sc_sa_map_write(mbox);442	if (!map_req) {443		otx2_mbox_reset(&mbox->mbox, 0);444		ret = -ENOMEM;445		goto fail;446	}447 448	ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak,449				   salt, rxsc->ssci[assoc_num]);450	if (ret)451		goto fail;452 453	plcy_req->sa_index[0] = rxsc->hw_sa_id[assoc_num];454	plcy_req->sa_cnt = 1;455	plcy_req->dir = MCS_RX;456 457	map_req->sa_index = rxsc->hw_sa_id[assoc_num];458	map_req->sa_in_use = sa_in_use;459	map_req->sc_id = rxsc->hw_sc_id;460	map_req->an = assoc_num;461 462	/* Send two messages together */463	ret = otx2_sync_mbox_msg(mbox);464 465fail:466	mutex_unlock(&mbox->lock);467	return ret;468}469 470static int cn10k_mcs_write_rx_sa_pn(struct otx2_nic *pfvf,471				    struct cn10k_mcs_rxsc *rxsc,472				    u8 assoc_num, u64 next_pn)473{474	struct mcs_pn_table_write_req *req;475	struct mbox *mbox = &pfvf->mbox;476	int ret;477 478	mutex_lock(&mbox->lock);479 480	req = otx2_mbox_alloc_msg_mcs_pn_table_write(mbox);481	if (!req) {482		ret = -ENOMEM;483		goto fail;484	}485 486	req->pn_id = rxsc->hw_sa_id[assoc_num];487	req->next_pn = next_pn;488	req->dir = MCS_RX;489 490	ret = otx2_sync_mbox_msg(mbox);491 492fail:493	mutex_unlock(&mbox->lock);494	return ret;495}496 497static int cn10k_mcs_write_tx_secy(struct otx2_nic *pfvf,498				   struct macsec_secy *secy,499				   struct cn10k_mcs_txsc *txsc)500{501	struct mcs_secy_plcy_write_req *req;502	struct mbox *mbox = &pfvf->mbox;503	struct macsec_tx_sc *sw_tx_sc;504	u8 sectag_tci = 0;505	u8 tag_offset;506	u64 policy;507	u8 cipher;508	int ret;509 510	/* Insert SecTag after 12 bytes (DA+SA) or 16 bytes511	 * if VLAN tag needs to be sent in clear text.512	 */513	tag_offset = txsc->vlan_dev ? 16 : 12;514	sw_tx_sc = &secy->tx_sc;515 516	mutex_lock(&mbox->lock);517 518	req = otx2_mbox_alloc_msg_mcs_secy_plcy_write(mbox);519	if (!req) {520		ret = -ENOMEM;521		goto fail;522	}523 524	if (sw_tx_sc->send_sci) {525		sectag_tci |= MCS_TCI_SC;526	} else {527		if (sw_tx_sc->end_station)528			sectag_tci |= MCS_TCI_ES;529		if (sw_tx_sc->scb)530			sectag_tci |= MCS_TCI_SCB;531	}532 533	if (sw_tx_sc->encrypt)534		sectag_tci |= (MCS_TCI_E | MCS_TCI_C);535 536	policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU, secy->netdev->mtu);537	/* Write SecTag excluding AN bits(1..0) */538	policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_TCI, sectag_tci >> 2);539	policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_OFFSET, tag_offset);540	policy |= MCS_TX_SECY_PLCY_INS_MODE;541	policy |= MCS_TX_SECY_PLCY_AUTH_ENA;542 543	switch (secy->key_len) {544	case 16:545		cipher = secy->xpn ? MCS_GCM_AES_XPN_128 : MCS_GCM_AES_128;546		break;547	case 32:548		cipher = secy->xpn ? MCS_GCM_AES_XPN_256 : MCS_GCM_AES_256;549		break;550	default:551		cipher = MCS_GCM_AES_128;552		dev_warn(pfvf->dev, "Unsupported key length\n");553		break;554	}555 556	policy |= FIELD_PREP(MCS_TX_SECY_PLCY_CIP, cipher);557 558	if (secy->protect_frames)559		policy |= MCS_TX_SECY_PLCY_PROTECT;560 561	/* If the encodingsa does not exist/active and protect is562	 * not set then frames can be sent out as it is. Hence enable563	 * the policy irrespective of secy operational when !protect.564	 */565	if (!secy->protect_frames || secy->operational)566		policy |= MCS_TX_SECY_PLCY_ENA;567 568	req->plcy = policy;569	req->secy_id = txsc->hw_secy_id_tx;570	req->dir = MCS_TX;571 572	ret = otx2_sync_mbox_msg(mbox);573 574fail:575	mutex_unlock(&mbox->lock);576	return ret;577}578 579static int cn10k_mcs_write_tx_flowid(struct otx2_nic *pfvf,580				     struct macsec_secy *secy,581				     struct cn10k_mcs_txsc *txsc)582{583	struct mcs_flowid_entry_write_req *req;584	struct mbox *mbox = &pfvf->mbox;585	u64 mac_sa;586	int ret;587 588	mutex_lock(&mbox->lock);589 590	req = otx2_mbox_alloc_msg_mcs_flowid_entry_write(mbox);591	if (!req) {592		ret = -ENOMEM;593		goto fail;594	}595 596	mac_sa = ether_addr_to_u64(secy->netdev->dev_addr);597 598	req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_SA_MASK, mac_sa);599	req->data[1] = FIELD_PREP(MCS_TCAM1_MAC_SA_MASK, mac_sa >> 16);600 601	req->mask[0] = ~0ULL;602	req->mask[0] &= ~MCS_TCAM0_MAC_SA_MASK;603 604	req->mask[1] = ~0ULL;605	req->mask[1] &= ~MCS_TCAM1_MAC_SA_MASK;606 607	req->mask[2] = ~0ULL;608	req->mask[3] = ~0ULL;609 610	req->flow_id = txsc->hw_flow_id;611	req->secy_id = txsc->hw_secy_id_tx;612	req->sc_id = txsc->hw_sc_id;613	req->sci = (__force u64)cpu_to_be64((__force u64)secy->sci);614	req->dir = MCS_TX;615	/* This can be enabled since stack xmits packets only when interface is up */616	req->ena = 1;617 618	ret = otx2_sync_mbox_msg(mbox);619 620fail:621	mutex_unlock(&mbox->lock);622	return ret;623}624 625static int cn10k_mcs_link_tx_sa2sc(struct otx2_nic *pfvf,626				   struct macsec_secy *secy,627				   struct cn10k_mcs_txsc *txsc,628				   u8 sa_num, bool sa_active)629{630	struct mcs_tx_sc_sa_map *map_req;631	struct mbox *mbox = &pfvf->mbox;632	int ret;633 634	/* Link the encoding_sa only to SC out of all SAs */635	if (txsc->encoding_sa != sa_num)636		return 0;637 638	mutex_lock(&mbox->lock);639 640	map_req = otx2_mbox_alloc_msg_mcs_tx_sc_sa_map_write(mbox);641	if (!map_req) {642		otx2_mbox_reset(&mbox->mbox, 0);643		ret = -ENOMEM;644		goto fail;645	}646 647	map_req->sa_index0 = txsc->hw_sa_id[sa_num];648	map_req->sa_index0_vld = sa_active;649	map_req->sectag_sci = (__force u64)cpu_to_be64((__force u64)secy->sci);650	map_req->sc_id = txsc->hw_sc_id;651 652	ret = otx2_sync_mbox_msg(mbox);653 654fail:655	mutex_unlock(&mbox->lock);656	return ret;657}658 659static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf,660				      struct macsec_secy *secy,661				      struct cn10k_mcs_txsc *txsc,662				      u8 assoc_num)663{664	struct mcs_sa_plcy_write_req *plcy_req;665	u8 *sak = txsc->sa_key[assoc_num];666	u8 *salt = txsc->salt[assoc_num];667	struct mbox *mbox = &pfvf->mbox;668	int ret;669 670	mutex_lock(&mbox->lock);671 672	plcy_req = otx2_mbox_alloc_msg_mcs_sa_plcy_write(mbox);673	if (!plcy_req) {674		ret = -ENOMEM;675		goto fail;676	}677 678	ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak,679				   salt, txsc->ssci[assoc_num]);680	if (ret)681		goto fail;682 683	plcy_req->plcy[0][8] = assoc_num;684	plcy_req->sa_index[0] = txsc->hw_sa_id[assoc_num];685	plcy_req->sa_cnt = 1;686	plcy_req->dir = MCS_TX;687 688	ret = otx2_sync_mbox_msg(mbox);689 690fail:691	mutex_unlock(&mbox->lock);692	return ret;693}694 695static int cn10k_write_tx_sa_pn(struct otx2_nic *pfvf,696				struct cn10k_mcs_txsc *txsc,697				u8 assoc_num, u64 next_pn)698{699	struct mcs_pn_table_write_req *req;700	struct mbox *mbox = &pfvf->mbox;701	int ret;702 703	mutex_lock(&mbox->lock);704 705	req = otx2_mbox_alloc_msg_mcs_pn_table_write(mbox);706	if (!req) {707		ret = -ENOMEM;708		goto fail;709	}710 711	req->pn_id = txsc->hw_sa_id[assoc_num];712	req->next_pn = next_pn;713	req->dir = MCS_TX;714 715	ret = otx2_sync_mbox_msg(mbox);716 717fail:718	mutex_unlock(&mbox->lock);719	return ret;720}721 722static int cn10k_mcs_ena_dis_flowid(struct otx2_nic *pfvf, u16 hw_flow_id,723				    bool enable, enum mcs_direction dir)724{725	struct mcs_flowid_ena_dis_entry *req;726	struct mbox *mbox = &pfvf->mbox;727	int ret;728 729	mutex_lock(&mbox->lock);730 731	req = otx2_mbox_alloc_msg_mcs_flowid_ena_entry(mbox);732	if (!req) {733		ret = -ENOMEM;734		goto fail;735	}736 737	req->flow_id = hw_flow_id;738	req->ena = enable;739	req->dir = dir;740 741	ret = otx2_sync_mbox_msg(mbox);742 743fail:744	mutex_unlock(&mbox->lock);745	return ret;746}747 748static int cn10k_mcs_sa_stats(struct otx2_nic *pfvf, u8 hw_sa_id,749			      struct mcs_sa_stats *rsp_p,750			      enum mcs_direction dir, bool clear)751{752	struct mcs_clear_stats *clear_req;753	struct mbox *mbox = &pfvf->mbox;754	struct mcs_stats_req *req;755	struct mcs_sa_stats *rsp;756	int ret;757 758	mutex_lock(&mbox->lock);759 760	req = otx2_mbox_alloc_msg_mcs_get_sa_stats(mbox);761	if (!req) {762		ret = -ENOMEM;763		goto fail;764	}765 766	req->id = hw_sa_id;767	req->dir = dir;768 769	if (!clear)770		goto send_msg;771 772	clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);773	if (!clear_req) {774		ret = -ENOMEM;775		goto fail;776	}777	clear_req->id = hw_sa_id;778	clear_req->dir = dir;779	clear_req->type = MCS_RSRC_TYPE_SA;780 781send_msg:782	ret = otx2_sync_mbox_msg(mbox);783	if (ret)784		goto fail;785 786	rsp = (struct mcs_sa_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,787						       0, &req->hdr);788	if (IS_ERR(rsp)) {789		ret = PTR_ERR(rsp);790		goto fail;791	}792 793	memcpy(rsp_p, rsp, sizeof(*rsp_p));794 795	mutex_unlock(&mbox->lock);796 797	return 0;798fail:799	mutex_unlock(&mbox->lock);800	return ret;801}802 803static int cn10k_mcs_sc_stats(struct otx2_nic *pfvf, u8 hw_sc_id,804			      struct mcs_sc_stats *rsp_p,805			      enum mcs_direction dir, bool clear)806{807	struct mcs_clear_stats *clear_req;808	struct mbox *mbox = &pfvf->mbox;809	struct mcs_stats_req *req;810	struct mcs_sc_stats *rsp;811	int ret;812 813	mutex_lock(&mbox->lock);814 815	req = otx2_mbox_alloc_msg_mcs_get_sc_stats(mbox);816	if (!req) {817		ret = -ENOMEM;818		goto fail;819	}820 821	req->id = hw_sc_id;822	req->dir = dir;823 824	if (!clear)825		goto send_msg;826 827	clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);828	if (!clear_req) {829		ret = -ENOMEM;830		goto fail;831	}832	clear_req->id = hw_sc_id;833	clear_req->dir = dir;834	clear_req->type = MCS_RSRC_TYPE_SC;835 836send_msg:837	ret = otx2_sync_mbox_msg(mbox);838	if (ret)839		goto fail;840 841	rsp = (struct mcs_sc_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,842						       0, &req->hdr);843	if (IS_ERR(rsp)) {844		ret = PTR_ERR(rsp);845		goto fail;846	}847 848	memcpy(rsp_p, rsp, sizeof(*rsp_p));849 850	mutex_unlock(&mbox->lock);851 852	return 0;853fail:854	mutex_unlock(&mbox->lock);855	return ret;856}857 858static int cn10k_mcs_secy_stats(struct otx2_nic *pfvf, u8 hw_secy_id,859				struct mcs_secy_stats *rsp_p,860				enum mcs_direction dir, bool clear)861{862	struct mcs_clear_stats *clear_req;863	struct mbox *mbox = &pfvf->mbox;864	struct mcs_secy_stats *rsp;865	struct mcs_stats_req *req;866	int ret;867 868	mutex_lock(&mbox->lock);869 870	req = otx2_mbox_alloc_msg_mcs_get_secy_stats(mbox);871	if (!req) {872		ret = -ENOMEM;873		goto fail;874	}875 876	req->id = hw_secy_id;877	req->dir = dir;878 879	if (!clear)880		goto send_msg;881 882	clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);883	if (!clear_req) {884		ret = -ENOMEM;885		goto fail;886	}887	clear_req->id = hw_secy_id;888	clear_req->dir = dir;889	clear_req->type = MCS_RSRC_TYPE_SECY;890 891send_msg:892	ret = otx2_sync_mbox_msg(mbox);893	if (ret)894		goto fail;895 896	rsp = (struct mcs_secy_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,897							 0, &req->hdr);898	if (IS_ERR(rsp)) {899		ret = PTR_ERR(rsp);900		goto fail;901	}902 903	memcpy(rsp_p, rsp, sizeof(*rsp_p));904 905	mutex_unlock(&mbox->lock);906 907	return 0;908fail:909	mutex_unlock(&mbox->lock);910	return ret;911}912 913static struct cn10k_mcs_txsc *cn10k_mcs_create_txsc(struct otx2_nic *pfvf)914{915	struct cn10k_mcs_txsc *txsc;916	int ret;917 918	txsc = kzalloc(sizeof(*txsc), GFP_KERNEL);919	if (!txsc)920		return ERR_PTR(-ENOMEM);921 922	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,923				   &txsc->hw_flow_id);924	if (ret)925		goto fail;926 927	/* For a SecY, one TX secy and one RX secy HW resources are needed */928	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,929				   &txsc->hw_secy_id_tx);930	if (ret)931		goto free_flowid;932 933	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,934				   &txsc->hw_secy_id_rx);935	if (ret)936		goto free_tx_secy;937 938	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SC,939				   &txsc->hw_sc_id);940	if (ret)941		goto free_rx_secy;942 943	return txsc;944free_rx_secy:945	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,946			    txsc->hw_secy_id_rx, false);947free_tx_secy:948	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,949			    txsc->hw_secy_id_tx, false);950free_flowid:951	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,952			    txsc->hw_flow_id, false);953fail:954	kfree(txsc);955	return ERR_PTR(ret);956}957 958/* Free Tx SC and its SAs(if any) resources to AF959 */960static void cn10k_mcs_delete_txsc(struct otx2_nic *pfvf,961				  struct cn10k_mcs_txsc *txsc)962{963	u8 sa_bmap = txsc->sa_bmap;964	u8 sa_num = 0;965 966	while (sa_bmap) {967		if (sa_bmap & 1) {968			cn10k_mcs_write_tx_sa_plcy(pfvf, txsc->sw_secy,969						   txsc, sa_num);970			cn10k_mcs_free_txsa(pfvf, txsc->hw_sa_id[sa_num]);971		}972		sa_num++;973		sa_bmap >>= 1;974	}975 976	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SC,977			    txsc->hw_sc_id, false);978	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,979			    txsc->hw_secy_id_rx, false);980	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,981			    txsc->hw_secy_id_tx, false);982	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,983			    txsc->hw_flow_id, false);984}985 986static struct cn10k_mcs_rxsc *cn10k_mcs_create_rxsc(struct otx2_nic *pfvf)987{988	struct cn10k_mcs_rxsc *rxsc;989	int ret;990 991	rxsc = kzalloc(sizeof(*rxsc), GFP_KERNEL);992	if (!rxsc)993		return ERR_PTR(-ENOMEM);994 995	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,996				   &rxsc->hw_flow_id);997	if (ret)998		goto fail;999 1000	ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SC,1001				   &rxsc->hw_sc_id);1002	if (ret)1003		goto free_flowid;1004 1005	return rxsc;1006free_flowid:1007	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,1008			    rxsc->hw_flow_id, false);1009fail:1010	kfree(rxsc);1011	return ERR_PTR(ret);1012}1013 1014/* Free Rx SC and its SAs(if any) resources to AF1015 */1016static void cn10k_mcs_delete_rxsc(struct otx2_nic *pfvf,1017				  struct cn10k_mcs_rxsc *rxsc)1018{1019	u8 sa_bmap = rxsc->sa_bmap;1020	u8 sa_num = 0;1021 1022	while (sa_bmap) {1023		if (sa_bmap & 1) {1024			cn10k_mcs_write_rx_sa_plcy(pfvf, rxsc->sw_secy, rxsc,1025						   sa_num, false);1026			cn10k_mcs_free_rxsa(pfvf, rxsc->hw_sa_id[sa_num]);1027		}1028		sa_num++;1029		sa_bmap >>= 1;1030	}1031 1032	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SC,1033			    rxsc->hw_sc_id, false);1034	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,1035			    rxsc->hw_flow_id, false);1036}1037 1038static int cn10k_mcs_secy_tx_cfg(struct otx2_nic *pfvf, struct macsec_secy *secy,1039				 struct cn10k_mcs_txsc *txsc,1040				 struct macsec_tx_sa *sw_tx_sa, u8 sa_num)1041{1042	if (sw_tx_sa) {1043		cn10k_mcs_write_tx_sa_plcy(pfvf, secy, txsc, sa_num);1044		cn10k_write_tx_sa_pn(pfvf, txsc, sa_num, sw_tx_sa->next_pn);1045		cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc, sa_num,1046					sw_tx_sa->active);1047	}1048 1049	cn10k_mcs_write_tx_secy(pfvf, secy, txsc);1050	cn10k_mcs_write_tx_flowid(pfvf, secy, txsc);1051	/* When updating secy, change RX secy also */1052	cn10k_mcs_write_rx_secy(pfvf, secy, txsc->hw_secy_id_rx);1053 1054	return 0;1055}1056 1057static int cn10k_mcs_secy_rx_cfg(struct otx2_nic *pfvf,1058				 struct macsec_secy *secy, u8 hw_secy_id)1059{1060	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1061	struct cn10k_mcs_rxsc *mcs_rx_sc;1062	struct macsec_rx_sc *sw_rx_sc;1063	struct macsec_rx_sa *sw_rx_sa;1064	u8 sa_num;1065 1066	for (sw_rx_sc = rcu_dereference_bh(secy->rx_sc); sw_rx_sc && sw_rx_sc->active;1067	     sw_rx_sc = rcu_dereference_bh(sw_rx_sc->next)) {1068		mcs_rx_sc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);1069		if (unlikely(!mcs_rx_sc))1070			continue;1071 1072		for (sa_num = 0; sa_num < CN10K_MCS_SA_PER_SC; sa_num++) {1073			sw_rx_sa = rcu_dereference_bh(sw_rx_sc->sa[sa_num]);1074			if (!sw_rx_sa)1075				continue;1076 1077			cn10k_mcs_write_rx_sa_plcy(pfvf, secy, mcs_rx_sc,1078						   sa_num, sw_rx_sa->active);1079			cn10k_mcs_write_rx_sa_pn(pfvf, mcs_rx_sc, sa_num,1080						 sw_rx_sa->next_pn);1081		}1082 1083		cn10k_mcs_write_rx_flowid(pfvf, mcs_rx_sc, hw_secy_id);1084		cn10k_mcs_write_sc_cam(pfvf, mcs_rx_sc, hw_secy_id);1085	}1086 1087	return 0;1088}1089 1090static int cn10k_mcs_disable_rxscs(struct otx2_nic *pfvf,1091				   struct macsec_secy *secy,1092				   bool delete)1093{1094	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1095	struct cn10k_mcs_rxsc *mcs_rx_sc;1096	struct macsec_rx_sc *sw_rx_sc;1097	int ret;1098 1099	for (sw_rx_sc = rcu_dereference_bh(secy->rx_sc); sw_rx_sc && sw_rx_sc->active;1100	     sw_rx_sc = rcu_dereference_bh(sw_rx_sc->next)) {1101		mcs_rx_sc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);1102		if (unlikely(!mcs_rx_sc))1103			continue;1104 1105		ret = cn10k_mcs_ena_dis_flowid(pfvf, mcs_rx_sc->hw_flow_id,1106					       false, MCS_RX);1107		if (ret)1108			dev_err(pfvf->dev, "Failed to disable TCAM for SC %d\n",1109				mcs_rx_sc->hw_sc_id);1110		if (delete) {1111			cn10k_mcs_delete_rxsc(pfvf, mcs_rx_sc);1112			list_del(&mcs_rx_sc->entry);1113			kfree(mcs_rx_sc);1114		}1115	}1116 1117	return 0;1118}1119 1120static void cn10k_mcs_sync_stats(struct otx2_nic *pfvf, struct macsec_secy *secy,1121				 struct cn10k_mcs_txsc *txsc)1122{1123	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1124	struct mcs_secy_stats rx_rsp = { 0 };1125	struct mcs_sc_stats sc_rsp = { 0 };1126	struct cn10k_mcs_rxsc *rxsc;1127 1128	/* Because of shared counters for some stats in the hardware, when1129	 * updating secy policy take a snapshot of current stats and reset them.1130	 * Below are the effected stats because of shared counters.1131	 */1132 1133	/* Check if sync is really needed */1134	if (secy->validate_frames == txsc->last_validate_frames &&1135	    secy->replay_protect == txsc->last_replay_protect)1136		return;1137 1138	cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_rx, &rx_rsp, MCS_RX, true);1139 1140	txsc->stats.InPktsBadTag += rx_rsp.pkt_badtag_cnt;1141	txsc->stats.InPktsUnknownSCI += rx_rsp.pkt_nosa_cnt;1142	txsc->stats.InPktsNoSCI += rx_rsp.pkt_nosaerror_cnt;1143	if (txsc->last_validate_frames == MACSEC_VALIDATE_STRICT)1144		txsc->stats.InPktsNoTag += rx_rsp.pkt_untaged_cnt;1145	else1146		txsc->stats.InPktsUntagged += rx_rsp.pkt_untaged_cnt;1147 1148	list_for_each_entry(rxsc, &cfg->rxsc_list, entry) {1149		cn10k_mcs_sc_stats(pfvf, rxsc->hw_sc_id, &sc_rsp, MCS_RX, true);1150 1151		rxsc->stats.InOctetsValidated += sc_rsp.octet_validate_cnt;1152		rxsc->stats.InOctetsDecrypted += sc_rsp.octet_decrypt_cnt;1153 1154		rxsc->stats.InPktsInvalid += sc_rsp.pkt_invalid_cnt;1155		rxsc->stats.InPktsNotValid += sc_rsp.pkt_notvalid_cnt;1156 1157		if (txsc->last_replay_protect)1158			rxsc->stats.InPktsLate += sc_rsp.pkt_late_cnt;1159		else1160			rxsc->stats.InPktsDelayed += sc_rsp.pkt_late_cnt;1161 1162		if (txsc->last_validate_frames == MACSEC_VALIDATE_DISABLED)1163			rxsc->stats.InPktsUnchecked += sc_rsp.pkt_unchecked_cnt;1164		else1165			rxsc->stats.InPktsOK += sc_rsp.pkt_unchecked_cnt;1166	}1167 1168	txsc->last_validate_frames = secy->validate_frames;1169	txsc->last_replay_protect = secy->replay_protect;1170}1171 1172static int cn10k_mdo_open(struct macsec_context *ctx)1173{1174	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1175	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1176	struct macsec_secy *secy = ctx->secy;1177	struct macsec_tx_sa *sw_tx_sa;1178	struct cn10k_mcs_txsc *txsc;1179	u8 sa_num;1180	int err;1181 1182	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1183	if (!txsc)1184		return -ENOENT;1185 1186	sa_num = txsc->encoding_sa;1187	sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[sa_num]);1188 1189	err = cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, sw_tx_sa, sa_num);1190	if (err)1191		return err;1192 1193	return cn10k_mcs_secy_rx_cfg(pfvf, secy, txsc->hw_secy_id_rx);1194}1195 1196static int cn10k_mdo_stop(struct macsec_context *ctx)1197{1198	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1199	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1200	struct cn10k_mcs_txsc *txsc;1201	int err;1202 1203	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1204	if (!txsc)1205		return -ENOENT;1206 1207	err = cn10k_mcs_ena_dis_flowid(pfvf, txsc->hw_flow_id, false, MCS_TX);1208	if (err)1209		return err;1210 1211	return cn10k_mcs_disable_rxscs(pfvf, ctx->secy, false);1212}1213 1214static int cn10k_mdo_add_secy(struct macsec_context *ctx)1215{1216	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1217	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1218	struct macsec_secy *secy = ctx->secy;1219	struct cn10k_mcs_txsc *txsc;1220 1221	if (secy->icv_len != MACSEC_DEFAULT_ICV_LEN)1222		return -EOPNOTSUPP;1223 1224	txsc = cn10k_mcs_create_txsc(pfvf);1225	if (IS_ERR(txsc))1226		return -ENOSPC;1227 1228	txsc->sw_secy = secy;1229	txsc->encoding_sa = secy->tx_sc.encoding_sa;1230	txsc->last_validate_frames = secy->validate_frames;1231	txsc->last_replay_protect = secy->replay_protect;1232	txsc->vlan_dev = is_vlan_dev(ctx->netdev);1233 1234	list_add(&txsc->entry, &cfg->txsc_list);1235 1236	if (netif_running(secy->netdev))1237		return cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, NULL, 0);1238 1239	return 0;1240}1241 1242static int cn10k_mdo_upd_secy(struct macsec_context *ctx)1243{1244	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1245	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1246	struct macsec_secy *secy = ctx->secy;1247	struct macsec_tx_sa *sw_tx_sa;1248	struct cn10k_mcs_txsc *txsc;1249	bool active;1250	u8 sa_num;1251	int err;1252 1253	txsc = cn10k_mcs_get_txsc(cfg, secy);1254	if (!txsc)1255		return -ENOENT;1256 1257	/* Encoding SA got changed */1258	if (txsc->encoding_sa != secy->tx_sc.encoding_sa) {1259		txsc->encoding_sa = secy->tx_sc.encoding_sa;1260		sa_num = txsc->encoding_sa;1261		sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[sa_num]);1262		active = sw_tx_sa ? sw_tx_sa->active : false;1263		cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc, sa_num, active);1264	}1265 1266	if (netif_running(secy->netdev)) {1267		cn10k_mcs_sync_stats(pfvf, secy, txsc);1268 1269		err = cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, NULL, 0);1270		if (err)1271			return err;1272	}1273 1274	return 0;1275}1276 1277static int cn10k_mdo_del_secy(struct macsec_context *ctx)1278{1279	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1280	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1281	struct cn10k_mcs_txsc *txsc;1282 1283	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1284	if (!txsc)1285		return -ENOENT;1286 1287	cn10k_mcs_ena_dis_flowid(pfvf, txsc->hw_flow_id, false, MCS_TX);1288	cn10k_mcs_disable_rxscs(pfvf, ctx->secy, true);1289	cn10k_mcs_delete_txsc(pfvf, txsc);1290	list_del(&txsc->entry);1291	kfree(txsc);1292 1293	return 0;1294}1295 1296static int cn10k_mdo_add_txsa(struct macsec_context *ctx)1297{1298	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1299	struct macsec_tx_sa *sw_tx_sa = ctx->sa.tx_sa;1300	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1301	struct macsec_secy *secy = ctx->secy;1302	u8 sa_num = ctx->sa.assoc_num;1303	struct cn10k_mcs_txsc *txsc;1304	int err;1305 1306	txsc = cn10k_mcs_get_txsc(cfg, secy);1307	if (!txsc)1308		return -ENOENT;1309 1310	if (sa_num >= CN10K_MCS_SA_PER_SC)1311		return -EOPNOTSUPP;1312 1313	if (cn10k_mcs_alloc_txsa(pfvf, &txsc->hw_sa_id[sa_num]))1314		return -ENOSPC;1315 1316	memcpy(&txsc->sa_key[sa_num], ctx->sa.key, secy->key_len);1317	memcpy(&txsc->salt[sa_num], sw_tx_sa->key.salt.bytes, MACSEC_SALT_LEN);1318	txsc->ssci[sa_num] = sw_tx_sa->ssci;1319 1320	txsc->sa_bmap |= 1 << sa_num;1321 1322	if (netif_running(secy->netdev)) {1323		err = cn10k_mcs_write_tx_sa_plcy(pfvf, secy, txsc, sa_num);1324		if (err)1325			return err;1326 1327		err = cn10k_write_tx_sa_pn(pfvf, txsc, sa_num,1328					   sw_tx_sa->next_pn);1329		if (err)1330			return err;1331 1332		err = cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc,1333					      sa_num, sw_tx_sa->active);1334		if (err)1335			return err;1336	}1337 1338	return 0;1339}1340 1341static int cn10k_mdo_upd_txsa(struct macsec_context *ctx)1342{1343	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1344	struct macsec_tx_sa *sw_tx_sa = ctx->sa.tx_sa;1345	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1346	struct macsec_secy *secy = ctx->secy;1347	u8 sa_num = ctx->sa.assoc_num;1348	struct cn10k_mcs_txsc *txsc;1349	int err;1350 1351	txsc = cn10k_mcs_get_txsc(cfg, secy);1352	if (!txsc)1353		return -ENOENT;1354 1355	if (sa_num >= CN10K_MCS_SA_PER_SC)1356		return -EOPNOTSUPP;1357 1358	if (netif_running(secy->netdev)) {1359		/* Keys cannot be changed after creation */1360		if (ctx->sa.update_pn) {1361			err = cn10k_write_tx_sa_pn(pfvf, txsc, sa_num,1362						   sw_tx_sa->next_pn);1363			if (err)1364				return err;1365		}1366 1367		err = cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc,1368					      sa_num, sw_tx_sa->active);1369		if (err)1370			return err;1371	}1372 1373	return 0;1374}1375 1376static int cn10k_mdo_del_txsa(struct macsec_context *ctx)1377{1378	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1379	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1380	u8 sa_num = ctx->sa.assoc_num;1381	struct cn10k_mcs_txsc *txsc;1382 1383	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1384	if (!txsc)1385		return -ENOENT;1386 1387	if (sa_num >= CN10K_MCS_SA_PER_SC)1388		return -EOPNOTSUPP;1389 1390	cn10k_mcs_free_txsa(pfvf, txsc->hw_sa_id[sa_num]);1391	txsc->sa_bmap &= ~(1 << sa_num);1392 1393	return 0;1394}1395 1396static int cn10k_mdo_add_rxsc(struct macsec_context *ctx)1397{1398	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1399	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1400	struct macsec_secy *secy = ctx->secy;1401	struct cn10k_mcs_rxsc *rxsc;1402	struct cn10k_mcs_txsc *txsc;1403	int err;1404 1405	txsc = cn10k_mcs_get_txsc(cfg, secy);1406	if (!txsc)1407		return -ENOENT;1408 1409	rxsc = cn10k_mcs_create_rxsc(pfvf);1410	if (IS_ERR(rxsc))1411		return -ENOSPC;1412 1413	rxsc->sw_secy = ctx->secy;1414	rxsc->sw_rxsc = ctx->rx_sc;1415	list_add(&rxsc->entry, &cfg->rxsc_list);1416 1417	if (netif_running(secy->netdev)) {1418		err = cn10k_mcs_write_rx_flowid(pfvf, rxsc, txsc->hw_secy_id_rx);1419		if (err)1420			return err;1421 1422		err = cn10k_mcs_write_sc_cam(pfvf, rxsc, txsc->hw_secy_id_rx);1423		if (err)1424			return err;1425	}1426 1427	return 0;1428}1429 1430static int cn10k_mdo_upd_rxsc(struct macsec_context *ctx)1431{1432	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1433	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1434	struct macsec_secy *secy = ctx->secy;1435	bool enable = ctx->rx_sc->active;1436	struct cn10k_mcs_rxsc *rxsc;1437 1438	rxsc = cn10k_mcs_get_rxsc(cfg, secy, ctx->rx_sc);1439	if (!rxsc)1440		return -ENOENT;1441 1442	if (netif_running(secy->netdev))1443		return cn10k_mcs_ena_dis_flowid(pfvf, rxsc->hw_flow_id,1444						enable, MCS_RX);1445 1446	return 0;1447}1448 1449static int cn10k_mdo_del_rxsc(struct macsec_context *ctx)1450{1451	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1452	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1453	struct cn10k_mcs_rxsc *rxsc;1454 1455	rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, ctx->rx_sc);1456	if (!rxsc)1457		return -ENOENT;1458 1459	cn10k_mcs_ena_dis_flowid(pfvf, rxsc->hw_flow_id, false, MCS_RX);1460	cn10k_mcs_delete_rxsc(pfvf, rxsc);1461	list_del(&rxsc->entry);1462	kfree(rxsc);1463 1464	return 0;1465}1466 1467static int cn10k_mdo_add_rxsa(struct macsec_context *ctx)1468{1469	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1470	struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;1471	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1472	struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;1473	struct macsec_secy *secy = ctx->secy;1474	bool sa_in_use = rx_sa->active;1475	u8 sa_num = ctx->sa.assoc_num;1476	struct cn10k_mcs_rxsc *rxsc;1477	int err;1478 1479	rxsc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);1480	if (!rxsc)1481		return -ENOENT;1482 1483	if (sa_num >= CN10K_MCS_SA_PER_SC)1484		return -EOPNOTSUPP;1485 1486	if (cn10k_mcs_alloc_rxsa(pfvf, &rxsc->hw_sa_id[sa_num]))1487		return -ENOSPC;1488 1489	memcpy(&rxsc->sa_key[sa_num], ctx->sa.key, ctx->secy->key_len);1490	memcpy(&rxsc->salt[sa_num], rx_sa->key.salt.bytes, MACSEC_SALT_LEN);1491	rxsc->ssci[sa_num] = rx_sa->ssci;1492 1493	rxsc->sa_bmap |= 1 << sa_num;1494 1495	if (netif_running(secy->netdev)) {1496		err = cn10k_mcs_write_rx_sa_plcy(pfvf, secy, rxsc,1497						 sa_num, sa_in_use);1498		if (err)1499			return err;1500 1501		err = cn10k_mcs_write_rx_sa_pn(pfvf, rxsc, sa_num,1502					       rx_sa->next_pn);1503		if (err)1504			return err;1505	}1506 1507	return 0;1508}1509 1510static int cn10k_mdo_upd_rxsa(struct macsec_context *ctx)1511{1512	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1513	struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;1514	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1515	struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;1516	struct macsec_secy *secy = ctx->secy;1517	bool sa_in_use = rx_sa->active;1518	u8 sa_num = ctx->sa.assoc_num;1519	struct cn10k_mcs_rxsc *rxsc;1520	int err;1521 1522	rxsc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);1523	if (!rxsc)1524		return -ENOENT;1525 1526	if (sa_num >= CN10K_MCS_SA_PER_SC)1527		return -EOPNOTSUPP;1528 1529	if (netif_running(secy->netdev)) {1530		err = cn10k_mcs_write_rx_sa_plcy(pfvf, secy, rxsc, sa_num, sa_in_use);1531		if (err)1532			return err;1533 1534		if (!ctx->sa.update_pn)1535			return 0;1536 1537		err = cn10k_mcs_write_rx_sa_pn(pfvf, rxsc, sa_num,1538					       rx_sa->next_pn);1539		if (err)1540			return err;1541	}1542 1543	return 0;1544}1545 1546static int cn10k_mdo_del_rxsa(struct macsec_context *ctx)1547{1548	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1549	struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;1550	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1551	u8 sa_num = ctx->sa.assoc_num;1552	struct cn10k_mcs_rxsc *rxsc;1553 1554	rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, sw_rx_sc);1555	if (!rxsc)1556		return -ENOENT;1557 1558	if (sa_num >= CN10K_MCS_SA_PER_SC)1559		return -EOPNOTSUPP;1560 1561	cn10k_mcs_write_rx_sa_plcy(pfvf, ctx->secy, rxsc, sa_num, false);1562	cn10k_mcs_free_rxsa(pfvf, rxsc->hw_sa_id[sa_num]);1563 1564	rxsc->sa_bmap &= ~(1 << sa_num);1565 1566	return 0;1567}1568 1569static int cn10k_mdo_get_dev_stats(struct macsec_context *ctx)1570{1571	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1572	struct mcs_secy_stats tx_rsp = { 0 }, rx_rsp = { 0 };1573	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1574	struct macsec_secy *secy = ctx->secy;1575	struct cn10k_mcs_txsc *txsc;1576 1577	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1578	if (!txsc)1579		return -ENOENT;1580 1581	cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_tx, &tx_rsp, MCS_TX, false);1582	ctx->stats.dev_stats->OutPktsUntagged = tx_rsp.pkt_untagged_cnt;1583	ctx->stats.dev_stats->OutPktsTooLong = tx_rsp.pkt_toolong_cnt;1584 1585	cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_rx, &rx_rsp, MCS_RX, true);1586	txsc->stats.InPktsBadTag += rx_rsp.pkt_badtag_cnt;1587	txsc->stats.InPktsUnknownSCI += rx_rsp.pkt_nosa_cnt;1588	txsc->stats.InPktsNoSCI += rx_rsp.pkt_nosaerror_cnt;1589	if (secy->validate_frames == MACSEC_VALIDATE_STRICT)1590		txsc->stats.InPktsNoTag += rx_rsp.pkt_untaged_cnt;1591	else1592		txsc->stats.InPktsUntagged += rx_rsp.pkt_untaged_cnt;1593	txsc->stats.InPktsOverrun = 0;1594 1595	ctx->stats.dev_stats->InPktsNoTag = txsc->stats.InPktsNoTag;1596	ctx->stats.dev_stats->InPktsUntagged = txsc->stats.InPktsUntagged;1597	ctx->stats.dev_stats->InPktsBadTag = txsc->stats.InPktsBadTag;1598	ctx->stats.dev_stats->InPktsUnknownSCI = txsc->stats.InPktsUnknownSCI;1599	ctx->stats.dev_stats->InPktsNoSCI = txsc->stats.InPktsNoSCI;1600	ctx->stats.dev_stats->InPktsOverrun = txsc->stats.InPktsOverrun;1601 1602	return 0;1603}1604 1605static int cn10k_mdo_get_tx_sc_stats(struct macsec_context *ctx)1606{1607	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1608	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1609	struct mcs_sc_stats rsp = { 0 };1610	struct cn10k_mcs_txsc *txsc;1611 1612	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1613	if (!txsc)1614		return -ENOENT;1615 1616	cn10k_mcs_sc_stats(pfvf, txsc->hw_sc_id, &rsp, MCS_TX, false);1617 1618	ctx->stats.tx_sc_stats->OutPktsProtected = rsp.pkt_protected_cnt;1619	ctx->stats.tx_sc_stats->OutPktsEncrypted = rsp.pkt_encrypt_cnt;1620	ctx->stats.tx_sc_stats->OutOctetsProtected = rsp.octet_protected_cnt;1621	ctx->stats.tx_sc_stats->OutOctetsEncrypted = rsp.octet_encrypt_cnt;1622 1623	return 0;1624}1625 1626static int cn10k_mdo_get_tx_sa_stats(struct macsec_context *ctx)1627{1628	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1629	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1630	struct mcs_sa_stats rsp = { 0 };1631	u8 sa_num = ctx->sa.assoc_num;1632	struct cn10k_mcs_txsc *txsc;1633 1634	txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);1635	if (!txsc)1636		return -ENOENT;1637 1638	if (sa_num >= CN10K_MCS_SA_PER_SC)1639		return -EOPNOTSUPP;1640 1641	cn10k_mcs_sa_stats(pfvf, txsc->hw_sa_id[sa_num], &rsp, MCS_TX, false);1642 1643	ctx->stats.tx_sa_stats->OutPktsProtected = rsp.pkt_protected_cnt;1644	ctx->stats.tx_sa_stats->OutPktsEncrypted = rsp.pkt_encrypt_cnt;1645 1646	return 0;1647}1648 1649static int cn10k_mdo_get_rx_sc_stats(struct macsec_context *ctx)1650{1651	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1652	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1653	struct macsec_secy *secy = ctx->secy;1654	struct mcs_sc_stats rsp = { 0 };1655	struct cn10k_mcs_rxsc *rxsc;1656 1657	rxsc = cn10k_mcs_get_rxsc(cfg, secy, ctx->rx_sc);1658	if (!rxsc)1659		return -ENOENT;1660 1661	cn10k_mcs_sc_stats(pfvf, rxsc->hw_sc_id, &rsp, MCS_RX, true);1662 1663	rxsc->stats.InOctetsValidated += rsp.octet_validate_cnt;1664	rxsc->stats.InOctetsDecrypted += rsp.octet_decrypt_cnt;1665 1666	rxsc->stats.InPktsInvalid += rsp.pkt_invalid_cnt;1667	rxsc->stats.InPktsNotValid += rsp.pkt_notvalid_cnt;1668 1669	if (secy->replay_protect)1670		rxsc->stats.InPktsLate += rsp.pkt_late_cnt;1671	else1672		rxsc->stats.InPktsDelayed += rsp.pkt_late_cnt;1673 1674	if (secy->validate_frames == MACSEC_VALIDATE_DISABLED)1675		rxsc->stats.InPktsUnchecked += rsp.pkt_unchecked_cnt;1676	else1677		rxsc->stats.InPktsOK += rsp.pkt_unchecked_cnt;1678 1679	ctx->stats.rx_sc_stats->InOctetsValidated = rxsc->stats.InOctetsValidated;1680	ctx->stats.rx_sc_stats->InOctetsDecrypted = rxsc->stats.InOctetsDecrypted;1681	ctx->stats.rx_sc_stats->InPktsInvalid = rxsc->stats.InPktsInvalid;1682	ctx->stats.rx_sc_stats->InPktsNotValid = rxsc->stats.InPktsNotValid;1683	ctx->stats.rx_sc_stats->InPktsLate = rxsc->stats.InPktsLate;1684	ctx->stats.rx_sc_stats->InPktsDelayed = rxsc->stats.InPktsDelayed;1685	ctx->stats.rx_sc_stats->InPktsUnchecked = rxsc->stats.InPktsUnchecked;1686	ctx->stats.rx_sc_stats->InPktsOK = rxsc->stats.InPktsOK;1687 1688	return 0;1689}1690 1691static int cn10k_mdo_get_rx_sa_stats(struct macsec_context *ctx)1692{1693	struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);1694	struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;1695	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1696	struct mcs_sa_stats rsp = { 0 };1697	u8 sa_num = ctx->sa.assoc_num;1698	struct cn10k_mcs_rxsc *rxsc;1699 1700	rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, sw_rx_sc);1701	if (!rxsc)1702		return -ENOENT;1703 1704	if (sa_num >= CN10K_MCS_SA_PER_SC)1705		return -EOPNOTSUPP;1706 1707	cn10k_mcs_sa_stats(pfvf, rxsc->hw_sa_id[sa_num], &rsp, MCS_RX, false);1708 1709	ctx->stats.rx_sa_stats->InPktsOK = rsp.pkt_ok_cnt;1710	ctx->stats.rx_sa_stats->InPktsInvalid = rsp.pkt_invalid_cnt;1711	ctx->stats.rx_sa_stats->InPktsNotValid = rsp.pkt_notvalid_cnt;1712	ctx->stats.rx_sa_stats->InPktsNotUsingSA = rsp.pkt_nosaerror_cnt;1713	ctx->stats.rx_sa_stats->InPktsUnusedSA = rsp.pkt_nosa_cnt;1714 1715	return 0;1716}1717 1718static const struct macsec_ops cn10k_mcs_ops = {1719	.mdo_dev_open = cn10k_mdo_open,1720	.mdo_dev_stop = cn10k_mdo_stop,1721	.mdo_add_secy = cn10k_mdo_add_secy,1722	.mdo_upd_secy = cn10k_mdo_upd_secy,1723	.mdo_del_secy = cn10k_mdo_del_secy,1724	.mdo_add_rxsc = cn10k_mdo_add_rxsc,1725	.mdo_upd_rxsc = cn10k_mdo_upd_rxsc,1726	.mdo_del_rxsc = cn10k_mdo_del_rxsc,1727	.mdo_add_rxsa = cn10k_mdo_add_rxsa,1728	.mdo_upd_rxsa = cn10k_mdo_upd_rxsa,1729	.mdo_del_rxsa = cn10k_mdo_del_rxsa,1730	.mdo_add_txsa = cn10k_mdo_add_txsa,1731	.mdo_upd_txsa = cn10k_mdo_upd_txsa,1732	.mdo_del_txsa = cn10k_mdo_del_txsa,1733	.mdo_get_dev_stats = cn10k_mdo_get_dev_stats,1734	.mdo_get_tx_sc_stats = cn10k_mdo_get_tx_sc_stats,1735	.mdo_get_tx_sa_stats = cn10k_mdo_get_tx_sa_stats,1736	.mdo_get_rx_sc_stats = cn10k_mdo_get_rx_sc_stats,1737	.mdo_get_rx_sa_stats = cn10k_mdo_get_rx_sa_stats,1738};1739 1740void cn10k_handle_mcs_event(struct otx2_nic *pfvf, struct mcs_intr_info *event)1741{1742	struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;1743	struct macsec_tx_sa *sw_tx_sa = NULL;1744	struct macsec_secy *secy = NULL;1745	struct cn10k_mcs_txsc *txsc;1746	u8 an;1747 1748	if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))1749		return;1750 1751	if (!(event->intr_mask & MCS_CPM_TX_PACKET_XPN_EQ0_INT))1752		return;1753 1754	/* Find the SecY to which the expired hardware SA is mapped */1755	list_for_each_entry(txsc, &cfg->txsc_list, entry) {1756		for (an = 0; an < CN10K_MCS_SA_PER_SC; an++)1757			if (txsc->hw_sa_id[an] == event->sa_id) {1758				secy = txsc->sw_secy;1759				sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[an]);1760			}1761	}1762 1763	if (secy && sw_tx_sa)1764		macsec_pn_wrapped(secy, sw_tx_sa);1765}1766 1767int cn10k_mcs_init(struct otx2_nic *pfvf)1768{1769	struct mbox *mbox = &pfvf->mbox;1770	struct cn10k_mcs_cfg *cfg;1771	struct mcs_intr_cfg *req;1772 1773	if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))1774		return 0;1775 1776	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);1777	if (!cfg)1778		return -ENOMEM;1779 1780	INIT_LIST_HEAD(&cfg->txsc_list);1781	INIT_LIST_HEAD(&cfg->rxsc_list);1782	pfvf->macsec_cfg = cfg;1783 1784	pfvf->netdev->features |= NETIF_F_HW_MACSEC;1785	pfvf->netdev->macsec_ops = &cn10k_mcs_ops;1786 1787	mutex_lock(&mbox->lock);1788 1789	req = otx2_mbox_alloc_msg_mcs_intr_cfg(mbox);1790	if (!req)1791		goto fail;1792 1793	req->intr_mask = MCS_CPM_TX_PACKET_XPN_EQ0_INT;1794 1795	if (otx2_sync_mbox_msg(mbox))1796		goto fail;1797 1798	mutex_unlock(&mbox->lock);1799 1800	return 0;1801fail:1802	dev_err(pfvf->dev, "Cannot notify PN wrapped event\n");1803	mutex_unlock(&mbox->lock);1804	return 0;1805}1806 1807void cn10k_mcs_free(struct otx2_nic *pfvf)1808{1809	if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))1810		return;1811 1812	cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY, 0, true);1813	cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY, 0, true);1814	kfree(pfvf->macsec_cfg);1815	pfvf->macsec_cfg = NULL;1816}1817