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