1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell MACSEC hardware offload driver
4 * Copyright (C) 2022 Marvell.
7 #include <crypto/skcipher.h>
8 #include <linux/rtnetlink.h>
9 #include <linux/bitfield.h>
10 #include "otx2_common.h"
12 #define MCS_TCAM0_MAC_DA_MASK GENMASK_ULL(47, 0)
13 #define MCS_TCAM0_MAC_SA_MASK GENMASK_ULL(63, 48)
14 #define MCS_TCAM1_MAC_SA_MASK GENMASK_ULL(31, 0)
15 #define MCS_TCAM1_ETYPE_MASK GENMASK_ULL(47, 32)
17 #define MCS_SA_MAP_MEM_SA_USE BIT_ULL(9)
19 #define MCS_RX_SECY_PLCY_RW_MASK GENMASK_ULL(49, 18)
20 #define MCS_RX_SECY_PLCY_RP BIT_ULL(17)
21 #define MCS_RX_SECY_PLCY_AUTH_ENA BIT_ULL(16)
22 #define MCS_RX_SECY_PLCY_CIP GENMASK_ULL(8, 5)
23 #define MCS_RX_SECY_PLCY_VAL GENMASK_ULL(2, 1)
24 #define MCS_RX_SECY_PLCY_ENA BIT_ULL(0)
26 #define MCS_TX_SECY_PLCY_MTU GENMASK_ULL(43, 28)
27 #define MCS_TX_SECY_PLCY_ST_TCI GENMASK_ULL(27, 22)
28 #define MCS_TX_SECY_PLCY_ST_OFFSET GENMASK_ULL(21, 15)
29 #define MCS_TX_SECY_PLCY_INS_MODE BIT_ULL(14)
30 #define MCS_TX_SECY_PLCY_AUTH_ENA BIT_ULL(13)
31 #define MCS_TX_SECY_PLCY_CIP GENMASK_ULL(5, 2)
32 #define MCS_TX_SECY_PLCY_PROTECT BIT_ULL(1)
33 #define MCS_TX_SECY_PLCY_ENA BIT_ULL(0)
35 #define MCS_GCM_AES_128 0
36 #define MCS_GCM_AES_256 1
37 #define MCS_GCM_AES_XPN_128 2
38 #define MCS_GCM_AES_XPN_256 3
40 #define MCS_TCI_ES 0x40 /* end station */
41 #define MCS_TCI_SC 0x20 /* SCI present */
42 #define MCS_TCI_SCB 0x10 /* epon */
43 #define MCS_TCI_E 0x08 /* encryption */
44 #define MCS_TCI_C 0x04 /* changed text */
46 #define CN10K_MAX_HASH_LEN 16
47 #define CN10K_MAX_SAK_LEN 32
49 static int cn10k_ecb_aes_encrypt(struct otx2_nic *pfvf, u8 *sak,
50 u16 sak_len, u8 *hash)
52 u8 data[CN10K_MAX_HASH_LEN] = { 0 };
53 struct skcipher_request *req = NULL;
54 struct scatterlist sg_src, sg_dst;
55 struct crypto_skcipher *tfm;
56 DECLARE_CRYPTO_WAIT(wait);
59 tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
61 dev_err(pfvf->dev, "failed to allocate transform for ecb-aes\n");
65 req = skcipher_request_alloc(tfm, GFP_KERNEL);
67 dev_err(pfvf->dev, "failed to allocate request for skcipher\n");
72 err = crypto_skcipher_setkey(tfm, sak, sak_len);
74 dev_err(pfvf->dev, "failed to set key for skcipher\n");
79 sg_init_one(&sg_src, data, CN10K_MAX_HASH_LEN);
80 sg_init_one(&sg_dst, hash, CN10K_MAX_HASH_LEN);
82 skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
83 skcipher_request_set_crypt(req, &sg_src, &sg_dst,
84 CN10K_MAX_HASH_LEN, NULL);
86 err = crypto_skcipher_encrypt(req);
87 err = crypto_wait_req(err, &wait);
90 skcipher_request_free(req);
92 crypto_free_skcipher(tfm);
96 static struct cn10k_mcs_txsc *cn10k_mcs_get_txsc(struct cn10k_mcs_cfg *cfg,
97 struct macsec_secy *secy)
99 struct cn10k_mcs_txsc *txsc;
101 list_for_each_entry(txsc, &cfg->txsc_list, entry) {
102 if (txsc->sw_secy == secy)
109 static struct cn10k_mcs_rxsc *cn10k_mcs_get_rxsc(struct cn10k_mcs_cfg *cfg,
110 struct macsec_secy *secy,
111 struct macsec_rx_sc *rx_sc)
113 struct cn10k_mcs_rxsc *rxsc;
115 list_for_each_entry(rxsc, &cfg->rxsc_list, entry) {
116 if (rxsc->sw_rxsc == rx_sc && rxsc->sw_secy == secy)
123 static const char *rsrc_name(enum mcs_rsrc_type rsrc_type)
126 case MCS_RSRC_TYPE_FLOWID:
128 case MCS_RSRC_TYPE_SC:
130 case MCS_RSRC_TYPE_SECY:
132 case MCS_RSRC_TYPE_SA:
141 static int cn10k_mcs_alloc_rsrc(struct otx2_nic *pfvf, enum mcs_direction dir,
142 enum mcs_rsrc_type type, u16 *rsrc_id)
144 struct mbox *mbox = &pfvf->mbox;
145 struct mcs_alloc_rsrc_req *req;
146 struct mcs_alloc_rsrc_rsp *rsp;
149 mutex_lock(&mbox->lock);
151 req = otx2_mbox_alloc_msg_mcs_alloc_resources(mbox);
155 req->rsrc_type = type;
159 ret = otx2_sync_mbox_msg(mbox);
163 rsp = (struct mcs_alloc_rsrc_rsp *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
165 if (IS_ERR(rsp) || req->rsrc_cnt != rsp->rsrc_cnt ||
166 req->rsrc_type != rsp->rsrc_type || req->dir != rsp->dir) {
171 switch (rsp->rsrc_type) {
172 case MCS_RSRC_TYPE_FLOWID:
173 *rsrc_id = rsp->flow_ids[0];
175 case MCS_RSRC_TYPE_SC:
176 *rsrc_id = rsp->sc_ids[0];
178 case MCS_RSRC_TYPE_SECY:
179 *rsrc_id = rsp->secy_ids[0];
181 case MCS_RSRC_TYPE_SA:
182 *rsrc_id = rsp->sa_ids[0];
189 mutex_unlock(&mbox->lock);
193 dev_err(pfvf->dev, "Failed to allocate %s %s resource\n",
194 dir == MCS_TX ? "TX" : "RX", rsrc_name(type));
195 mutex_unlock(&mbox->lock);
199 static void cn10k_mcs_free_rsrc(struct otx2_nic *pfvf, enum mcs_direction dir,
200 enum mcs_rsrc_type type, u16 hw_rsrc_id,
203 struct mcs_clear_stats *clear_req;
204 struct mbox *mbox = &pfvf->mbox;
205 struct mcs_free_rsrc_req *req;
207 mutex_lock(&mbox->lock);
209 clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);
213 clear_req->id = hw_rsrc_id;
214 clear_req->type = type;
215 clear_req->dir = dir;
217 req = otx2_mbox_alloc_msg_mcs_free_resources(mbox);
221 req->rsrc_id = hw_rsrc_id;
222 req->rsrc_type = type;
227 if (otx2_sync_mbox_msg(&pfvf->mbox))
230 mutex_unlock(&mbox->lock);
234 dev_err(pfvf->dev, "Failed to free %s %s resource\n",
235 dir == MCS_TX ? "TX" : "RX", rsrc_name(type));
236 mutex_unlock(&mbox->lock);
239 static int cn10k_mcs_alloc_txsa(struct otx2_nic *pfvf, u16 *hw_sa_id)
241 return cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SA, hw_sa_id);
244 static int cn10k_mcs_alloc_rxsa(struct otx2_nic *pfvf, u16 *hw_sa_id)
246 return cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SA, hw_sa_id);
249 static void cn10k_mcs_free_txsa(struct otx2_nic *pfvf, u16 hw_sa_id)
251 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SA, hw_sa_id, false);
254 static void cn10k_mcs_free_rxsa(struct otx2_nic *pfvf, u16 hw_sa_id)
256 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SA, hw_sa_id, false);
259 static int cn10k_mcs_write_rx_secy(struct otx2_nic *pfvf,
260 struct macsec_secy *secy, u8 hw_secy_id)
262 struct mcs_secy_plcy_write_req *req;
263 struct mbox *mbox = &pfvf->mbox;
268 mutex_lock(&mbox->lock);
270 req = otx2_mbox_alloc_msg_mcs_secy_plcy_write(mbox);
276 policy = FIELD_PREP(MCS_RX_SECY_PLCY_RW_MASK, secy->replay_window);
277 if (secy->replay_protect)
278 policy |= MCS_RX_SECY_PLCY_RP;
280 policy |= MCS_RX_SECY_PLCY_AUTH_ENA;
282 switch (secy->key_len) {
284 cipher = secy->xpn ? MCS_GCM_AES_XPN_128 : MCS_GCM_AES_128;
287 cipher = secy->xpn ? MCS_GCM_AES_XPN_256 : MCS_GCM_AES_256;
290 cipher = MCS_GCM_AES_128;
291 dev_warn(pfvf->dev, "Unsupported key length\n");
295 policy |= FIELD_PREP(MCS_RX_SECY_PLCY_CIP, cipher);
296 policy |= FIELD_PREP(MCS_RX_SECY_PLCY_VAL, secy->validate_frames);
298 policy |= MCS_RX_SECY_PLCY_ENA;
301 req->secy_id = hw_secy_id;
304 ret = otx2_sync_mbox_msg(mbox);
307 mutex_unlock(&mbox->lock);
311 static int cn10k_mcs_write_rx_flowid(struct otx2_nic *pfvf,
312 struct cn10k_mcs_rxsc *rxsc, u8 hw_secy_id)
314 struct macsec_rx_sc *sw_rx_sc = rxsc->sw_rxsc;
315 struct macsec_secy *secy = rxsc->sw_secy;
316 struct mcs_flowid_entry_write_req *req;
317 struct mbox *mbox = &pfvf->mbox;
321 mutex_lock(&mbox->lock);
323 req = otx2_mbox_alloc_msg_mcs_flowid_entry_write(mbox);
329 mac_da = ether_addr_to_u64(secy->netdev->dev_addr);
331 req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_DA_MASK, mac_da);
332 req->mask[0] = ~0ULL;
333 req->mask[0] = ~MCS_TCAM0_MAC_DA_MASK;
335 req->data[1] = FIELD_PREP(MCS_TCAM1_ETYPE_MASK, ETH_P_MACSEC);
336 req->mask[1] = ~0ULL;
337 req->mask[1] &= ~MCS_TCAM1_ETYPE_MASK;
339 req->mask[2] = ~0ULL;
340 req->mask[3] = ~0ULL;
342 req->flow_id = rxsc->hw_flow_id;
343 req->secy_id = hw_secy_id;
344 req->sc_id = rxsc->hw_sc_id;
347 if (sw_rx_sc->active)
350 ret = otx2_sync_mbox_msg(mbox);
353 mutex_unlock(&mbox->lock);
357 static int cn10k_mcs_write_sc_cam(struct otx2_nic *pfvf,
358 struct cn10k_mcs_rxsc *rxsc, u8 hw_secy_id)
360 struct macsec_rx_sc *sw_rx_sc = rxsc->sw_rxsc;
361 struct mcs_rx_sc_cam_write_req *sc_req;
362 struct mbox *mbox = &pfvf->mbox;
365 mutex_lock(&mbox->lock);
367 sc_req = otx2_mbox_alloc_msg_mcs_rx_sc_cam_write(mbox);
373 sc_req->sci = (__force u64)cpu_to_be64((__force u64)sw_rx_sc->sci);
374 sc_req->sc_id = rxsc->hw_sc_id;
375 sc_req->secy_id = hw_secy_id;
377 ret = otx2_sync_mbox_msg(mbox);
380 mutex_unlock(&mbox->lock);
384 static int cn10k_mcs_write_keys(struct otx2_nic *pfvf,
385 struct macsec_secy *secy,
386 struct mcs_sa_plcy_write_req *req,
387 u8 *sak, u8 *salt, ssci_t ssci)
389 u8 hash_rev[CN10K_MAX_HASH_LEN];
390 u8 sak_rev[CN10K_MAX_SAK_LEN];
391 u8 salt_rev[MACSEC_SALT_LEN];
392 u8 hash[CN10K_MAX_HASH_LEN];
396 err = cn10k_ecb_aes_encrypt(pfvf, sak, secy->key_len, hash);
398 dev_err(pfvf->dev, "Generating hash using ECB(AES) failed\n");
402 for (i = 0; i < secy->key_len; i++)
403 sak_rev[i] = sak[secy->key_len - 1 - i];
405 for (i = 0; i < CN10K_MAX_HASH_LEN; i++)
406 hash_rev[i] = hash[CN10K_MAX_HASH_LEN - 1 - i];
408 for (i = 0; i < MACSEC_SALT_LEN; i++)
409 salt_rev[i] = salt[MACSEC_SALT_LEN - 1 - i];
411 ssci_63_32 = (__force u32)cpu_to_be32((__force u32)ssci);
413 memcpy(&req->plcy[0][0], sak_rev, secy->key_len);
414 memcpy(&req->plcy[0][4], hash_rev, CN10K_MAX_HASH_LEN);
415 memcpy(&req->plcy[0][6], salt_rev, MACSEC_SALT_LEN);
416 req->plcy[0][7] |= (u64)ssci_63_32 << 32;
421 static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf,
422 struct macsec_secy *secy,
423 struct cn10k_mcs_rxsc *rxsc,
424 u8 assoc_num, bool sa_in_use)
426 struct mcs_sa_plcy_write_req *plcy_req;
427 u8 *sak = rxsc->sa_key[assoc_num];
428 u8 *salt = rxsc->salt[assoc_num];
429 struct mcs_rx_sc_sa_map *map_req;
430 struct mbox *mbox = &pfvf->mbox;
433 mutex_lock(&mbox->lock);
435 plcy_req = otx2_mbox_alloc_msg_mcs_sa_plcy_write(mbox);
441 map_req = otx2_mbox_alloc_msg_mcs_rx_sc_sa_map_write(mbox);
443 otx2_mbox_reset(&mbox->mbox, 0);
448 ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak,
449 salt, rxsc->ssci[assoc_num]);
453 plcy_req->sa_index[0] = rxsc->hw_sa_id[assoc_num];
454 plcy_req->sa_cnt = 1;
455 plcy_req->dir = MCS_RX;
457 map_req->sa_index = rxsc->hw_sa_id[assoc_num];
458 map_req->sa_in_use = sa_in_use;
459 map_req->sc_id = rxsc->hw_sc_id;
460 map_req->an = assoc_num;
462 /* Send two messages together */
463 ret = otx2_sync_mbox_msg(mbox);
466 mutex_unlock(&mbox->lock);
470 static int cn10k_mcs_write_rx_sa_pn(struct otx2_nic *pfvf,
471 struct cn10k_mcs_rxsc *rxsc,
472 u8 assoc_num, u64 next_pn)
474 struct mcs_pn_table_write_req *req;
475 struct mbox *mbox = &pfvf->mbox;
478 mutex_lock(&mbox->lock);
480 req = otx2_mbox_alloc_msg_mcs_pn_table_write(mbox);
486 req->pn_id = rxsc->hw_sa_id[assoc_num];
487 req->next_pn = next_pn;
490 ret = otx2_sync_mbox_msg(mbox);
493 mutex_unlock(&mbox->lock);
497 static int cn10k_mcs_write_tx_secy(struct otx2_nic *pfvf,
498 struct macsec_secy *secy,
499 struct cn10k_mcs_txsc *txsc)
501 struct mcs_secy_plcy_write_req *req;
502 struct mbox *mbox = &pfvf->mbox;
503 struct macsec_tx_sc *sw_tx_sc;
510 /* Insert SecTag after 12 bytes (DA+SA) or 16 bytes
511 * if VLAN tag needs to be sent in clear text.
513 tag_offset = txsc->vlan_dev ? 16 : 12;
514 sw_tx_sc = &secy->tx_sc;
516 mutex_lock(&mbox->lock);
518 req = otx2_mbox_alloc_msg_mcs_secy_plcy_write(mbox);
524 if (sw_tx_sc->send_sci) {
525 sectag_tci |= MCS_TCI_SC;
527 if (sw_tx_sc->end_station)
528 sectag_tci |= MCS_TCI_ES;
530 sectag_tci |= MCS_TCI_SCB;
533 if (sw_tx_sc->encrypt)
534 sectag_tci |= (MCS_TCI_E | MCS_TCI_C);
536 policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU, secy->netdev->mtu);
537 /* Write SecTag excluding AN bits(1..0) */
538 policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_TCI, sectag_tci >> 2);
539 policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_OFFSET, tag_offset);
540 policy |= MCS_TX_SECY_PLCY_INS_MODE;
541 policy |= MCS_TX_SECY_PLCY_AUTH_ENA;
543 switch (secy->key_len) {
545 cipher = secy->xpn ? MCS_GCM_AES_XPN_128 : MCS_GCM_AES_128;
548 cipher = secy->xpn ? MCS_GCM_AES_XPN_256 : MCS_GCM_AES_256;
551 cipher = MCS_GCM_AES_128;
552 dev_warn(pfvf->dev, "Unsupported key length\n");
556 policy |= FIELD_PREP(MCS_TX_SECY_PLCY_CIP, cipher);
558 if (secy->protect_frames)
559 policy |= MCS_TX_SECY_PLCY_PROTECT;
561 /* If the encodingsa does not exist/active and protect is
562 * not set then frames can be sent out as it is. Hence enable
563 * the policy irrespective of secy operational when !protect.
565 if (!secy->protect_frames || secy->operational)
566 policy |= MCS_TX_SECY_PLCY_ENA;
569 req->secy_id = txsc->hw_secy_id_tx;
572 ret = otx2_sync_mbox_msg(mbox);
575 mutex_unlock(&mbox->lock);
579 static int cn10k_mcs_write_tx_flowid(struct otx2_nic *pfvf,
580 struct macsec_secy *secy,
581 struct cn10k_mcs_txsc *txsc)
583 struct mcs_flowid_entry_write_req *req;
584 struct mbox *mbox = &pfvf->mbox;
588 mutex_lock(&mbox->lock);
590 req = otx2_mbox_alloc_msg_mcs_flowid_entry_write(mbox);
596 mac_sa = ether_addr_to_u64(secy->netdev->dev_addr);
598 req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_SA_MASK, mac_sa);
599 req->data[1] = FIELD_PREP(MCS_TCAM1_MAC_SA_MASK, mac_sa >> 16);
601 req->mask[0] = ~0ULL;
602 req->mask[0] &= ~MCS_TCAM0_MAC_SA_MASK;
604 req->mask[1] = ~0ULL;
605 req->mask[1] &= ~MCS_TCAM1_MAC_SA_MASK;
607 req->mask[2] = ~0ULL;
608 req->mask[3] = ~0ULL;
610 req->flow_id = txsc->hw_flow_id;
611 req->secy_id = txsc->hw_secy_id_tx;
612 req->sc_id = txsc->hw_sc_id;
613 req->sci = (__force u64)cpu_to_be64((__force u64)secy->sci);
615 /* This can be enabled since stack xmits packets only when interface is up */
618 ret = otx2_sync_mbox_msg(mbox);
621 mutex_unlock(&mbox->lock);
625 static int cn10k_mcs_link_tx_sa2sc(struct otx2_nic *pfvf,
626 struct macsec_secy *secy,
627 struct cn10k_mcs_txsc *txsc,
628 u8 sa_num, bool sa_active)
630 struct mcs_tx_sc_sa_map *map_req;
631 struct mbox *mbox = &pfvf->mbox;
634 /* Link the encoding_sa only to SC out of all SAs */
635 if (txsc->encoding_sa != sa_num)
638 mutex_lock(&mbox->lock);
640 map_req = otx2_mbox_alloc_msg_mcs_tx_sc_sa_map_write(mbox);
642 otx2_mbox_reset(&mbox->mbox, 0);
647 map_req->sa_index0 = txsc->hw_sa_id[sa_num];
648 map_req->sa_index0_vld = sa_active;
649 map_req->sectag_sci = (__force u64)cpu_to_be64((__force u64)secy->sci);
650 map_req->sc_id = txsc->hw_sc_id;
652 ret = otx2_sync_mbox_msg(mbox);
655 mutex_unlock(&mbox->lock);
659 static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf,
660 struct macsec_secy *secy,
661 struct cn10k_mcs_txsc *txsc,
664 struct mcs_sa_plcy_write_req *plcy_req;
665 u8 *sak = txsc->sa_key[assoc_num];
666 u8 *salt = txsc->salt[assoc_num];
667 struct mbox *mbox = &pfvf->mbox;
670 mutex_lock(&mbox->lock);
672 plcy_req = otx2_mbox_alloc_msg_mcs_sa_plcy_write(mbox);
678 ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak,
679 salt, txsc->ssci[assoc_num]);
683 plcy_req->plcy[0][8] = assoc_num;
684 plcy_req->sa_index[0] = txsc->hw_sa_id[assoc_num];
685 plcy_req->sa_cnt = 1;
686 plcy_req->dir = MCS_TX;
688 ret = otx2_sync_mbox_msg(mbox);
691 mutex_unlock(&mbox->lock);
695 static int cn10k_write_tx_sa_pn(struct otx2_nic *pfvf,
696 struct cn10k_mcs_txsc *txsc,
697 u8 assoc_num, u64 next_pn)
699 struct mcs_pn_table_write_req *req;
700 struct mbox *mbox = &pfvf->mbox;
703 mutex_lock(&mbox->lock);
705 req = otx2_mbox_alloc_msg_mcs_pn_table_write(mbox);
711 req->pn_id = txsc->hw_sa_id[assoc_num];
712 req->next_pn = next_pn;
715 ret = otx2_sync_mbox_msg(mbox);
718 mutex_unlock(&mbox->lock);
722 static int cn10k_mcs_ena_dis_flowid(struct otx2_nic *pfvf, u16 hw_flow_id,
723 bool enable, enum mcs_direction dir)
725 struct mcs_flowid_ena_dis_entry *req;
726 struct mbox *mbox = &pfvf->mbox;
729 mutex_lock(&mbox->lock);
731 req = otx2_mbox_alloc_msg_mcs_flowid_ena_entry(mbox);
737 req->flow_id = hw_flow_id;
741 ret = otx2_sync_mbox_msg(mbox);
744 mutex_unlock(&mbox->lock);
748 static int cn10k_mcs_sa_stats(struct otx2_nic *pfvf, u8 hw_sa_id,
749 struct mcs_sa_stats *rsp_p,
750 enum mcs_direction dir, bool clear)
752 struct mcs_clear_stats *clear_req;
753 struct mbox *mbox = &pfvf->mbox;
754 struct mcs_stats_req *req;
755 struct mcs_sa_stats *rsp;
758 mutex_lock(&mbox->lock);
760 req = otx2_mbox_alloc_msg_mcs_get_sa_stats(mbox);
772 clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);
777 clear_req->id = hw_sa_id;
778 clear_req->dir = dir;
779 clear_req->type = MCS_RSRC_TYPE_SA;
782 ret = otx2_sync_mbox_msg(mbox);
786 rsp = (struct mcs_sa_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
793 memcpy(rsp_p, rsp, sizeof(*rsp_p));
795 mutex_unlock(&mbox->lock);
799 mutex_unlock(&mbox->lock);
803 static int cn10k_mcs_sc_stats(struct otx2_nic *pfvf, u8 hw_sc_id,
804 struct mcs_sc_stats *rsp_p,
805 enum mcs_direction dir, bool clear)
807 struct mcs_clear_stats *clear_req;
808 struct mbox *mbox = &pfvf->mbox;
809 struct mcs_stats_req *req;
810 struct mcs_sc_stats *rsp;
813 mutex_lock(&mbox->lock);
815 req = otx2_mbox_alloc_msg_mcs_get_sc_stats(mbox);
827 clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);
832 clear_req->id = hw_sc_id;
833 clear_req->dir = dir;
834 clear_req->type = MCS_RSRC_TYPE_SC;
837 ret = otx2_sync_mbox_msg(mbox);
841 rsp = (struct mcs_sc_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
848 memcpy(rsp_p, rsp, sizeof(*rsp_p));
850 mutex_unlock(&mbox->lock);
854 mutex_unlock(&mbox->lock);
858 static int cn10k_mcs_secy_stats(struct otx2_nic *pfvf, u8 hw_secy_id,
859 struct mcs_secy_stats *rsp_p,
860 enum mcs_direction dir, bool clear)
862 struct mcs_clear_stats *clear_req;
863 struct mbox *mbox = &pfvf->mbox;
864 struct mcs_secy_stats *rsp;
865 struct mcs_stats_req *req;
868 mutex_lock(&mbox->lock);
870 req = otx2_mbox_alloc_msg_mcs_get_secy_stats(mbox);
876 req->id = hw_secy_id;
882 clear_req = otx2_mbox_alloc_msg_mcs_clear_stats(mbox);
887 clear_req->id = hw_secy_id;
888 clear_req->dir = dir;
889 clear_req->type = MCS_RSRC_TYPE_SECY;
892 ret = otx2_sync_mbox_msg(mbox);
896 rsp = (struct mcs_secy_stats *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
903 memcpy(rsp_p, rsp, sizeof(*rsp_p));
905 mutex_unlock(&mbox->lock);
909 mutex_unlock(&mbox->lock);
913 static struct cn10k_mcs_txsc *cn10k_mcs_create_txsc(struct otx2_nic *pfvf)
915 struct cn10k_mcs_txsc *txsc;
918 txsc = kzalloc(sizeof(*txsc), GFP_KERNEL);
920 return ERR_PTR(-ENOMEM);
922 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,
927 /* For a SecY, one TX secy and one RX secy HW resources are needed */
928 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,
929 &txsc->hw_secy_id_tx);
933 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,
934 &txsc->hw_secy_id_rx);
938 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SC,
945 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,
946 txsc->hw_secy_id_rx, false);
948 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,
949 txsc->hw_secy_id_tx, false);
951 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,
952 txsc->hw_flow_id, false);
958 /* Free Tx SC and its SAs(if any) resources to AF
960 static void cn10k_mcs_delete_txsc(struct otx2_nic *pfvf,
961 struct cn10k_mcs_txsc *txsc)
963 u8 sa_bmap = txsc->sa_bmap;
968 cn10k_mcs_write_tx_sa_plcy(pfvf, txsc->sw_secy,
970 cn10k_mcs_free_txsa(pfvf, txsc->hw_sa_id[sa_num]);
976 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SC,
977 txsc->hw_sc_id, false);
978 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY,
979 txsc->hw_secy_id_rx, false);
980 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY,
981 txsc->hw_secy_id_tx, false);
982 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,
983 txsc->hw_flow_id, false);
986 static struct cn10k_mcs_rxsc *cn10k_mcs_create_rxsc(struct otx2_nic *pfvf)
988 struct cn10k_mcs_rxsc *rxsc;
991 rxsc = kzalloc(sizeof(*rxsc), GFP_KERNEL);
993 return ERR_PTR(-ENOMEM);
995 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,
1000 ret = cn10k_mcs_alloc_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SC,
1007 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,
1008 rxsc->hw_flow_id, false);
1011 return ERR_PTR(ret);
1014 /* Free Rx SC and its SAs(if any) resources to AF
1016 static void cn10k_mcs_delete_rxsc(struct otx2_nic *pfvf,
1017 struct cn10k_mcs_rxsc *rxsc)
1019 u8 sa_bmap = rxsc->sa_bmap;
1024 cn10k_mcs_write_rx_sa_plcy(pfvf, rxsc->sw_secy, rxsc,
1026 cn10k_mcs_free_rxsa(pfvf, rxsc->hw_sa_id[sa_num]);
1032 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SC,
1033 rxsc->hw_sc_id, false);
1034 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,
1035 rxsc->hw_flow_id, false);
1038 static int cn10k_mcs_secy_tx_cfg(struct otx2_nic *pfvf, struct macsec_secy *secy,
1039 struct cn10k_mcs_txsc *txsc,
1040 struct macsec_tx_sa *sw_tx_sa, u8 sa_num)
1043 cn10k_mcs_write_tx_sa_plcy(pfvf, secy, txsc, sa_num);
1044 cn10k_write_tx_sa_pn(pfvf, txsc, sa_num, sw_tx_sa->next_pn);
1045 cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc, sa_num,
1049 cn10k_mcs_write_tx_secy(pfvf, secy, txsc);
1050 cn10k_mcs_write_tx_flowid(pfvf, secy, txsc);
1051 /* When updating secy, change RX secy also */
1052 cn10k_mcs_write_rx_secy(pfvf, secy, txsc->hw_secy_id_rx);
1057 static int cn10k_mcs_secy_rx_cfg(struct otx2_nic *pfvf,
1058 struct macsec_secy *secy, u8 hw_secy_id)
1060 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1061 struct cn10k_mcs_rxsc *mcs_rx_sc;
1062 struct macsec_rx_sc *sw_rx_sc;
1063 struct macsec_rx_sa *sw_rx_sa;
1066 for (sw_rx_sc = rcu_dereference_bh(secy->rx_sc); sw_rx_sc && sw_rx_sc->active;
1067 sw_rx_sc = rcu_dereference_bh(sw_rx_sc->next)) {
1068 mcs_rx_sc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);
1069 if (unlikely(!mcs_rx_sc))
1072 for (sa_num = 0; sa_num < CN10K_MCS_SA_PER_SC; sa_num++) {
1073 sw_rx_sa = rcu_dereference_bh(sw_rx_sc->sa[sa_num]);
1077 cn10k_mcs_write_rx_sa_plcy(pfvf, secy, mcs_rx_sc,
1078 sa_num, sw_rx_sa->active);
1079 cn10k_mcs_write_rx_sa_pn(pfvf, mcs_rx_sc, sa_num,
1083 cn10k_mcs_write_rx_flowid(pfvf, mcs_rx_sc, hw_secy_id);
1084 cn10k_mcs_write_sc_cam(pfvf, mcs_rx_sc, hw_secy_id);
1090 static int cn10k_mcs_disable_rxscs(struct otx2_nic *pfvf,
1091 struct macsec_secy *secy,
1094 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1095 struct cn10k_mcs_rxsc *mcs_rx_sc;
1096 struct macsec_rx_sc *sw_rx_sc;
1099 for (sw_rx_sc = rcu_dereference_bh(secy->rx_sc); sw_rx_sc && sw_rx_sc->active;
1100 sw_rx_sc = rcu_dereference_bh(sw_rx_sc->next)) {
1101 mcs_rx_sc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);
1102 if (unlikely(!mcs_rx_sc))
1105 ret = cn10k_mcs_ena_dis_flowid(pfvf, mcs_rx_sc->hw_flow_id,
1108 dev_err(pfvf->dev, "Failed to disable TCAM for SC %d\n",
1109 mcs_rx_sc->hw_sc_id);
1111 cn10k_mcs_delete_rxsc(pfvf, mcs_rx_sc);
1112 list_del(&mcs_rx_sc->entry);
1120 static void cn10k_mcs_sync_stats(struct otx2_nic *pfvf, struct macsec_secy *secy,
1121 struct cn10k_mcs_txsc *txsc)
1123 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1124 struct mcs_secy_stats rx_rsp = { 0 };
1125 struct mcs_sc_stats sc_rsp = { 0 };
1126 struct cn10k_mcs_rxsc *rxsc;
1128 /* Because of shared counters for some stats in the hardware, when
1129 * updating secy policy take a snapshot of current stats and reset them.
1130 * Below are the effected stats because of shared counters.
1133 /* Check if sync is really needed */
1134 if (secy->validate_frames == txsc->last_validate_frames &&
1135 secy->replay_protect == txsc->last_replay_protect)
1138 cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_rx, &rx_rsp, MCS_RX, true);
1140 txsc->stats.InPktsBadTag += rx_rsp.pkt_badtag_cnt;
1141 txsc->stats.InPktsUnknownSCI += rx_rsp.pkt_nosa_cnt;
1142 txsc->stats.InPktsNoSCI += rx_rsp.pkt_nosaerror_cnt;
1143 if (txsc->last_validate_frames == MACSEC_VALIDATE_STRICT)
1144 txsc->stats.InPktsNoTag += rx_rsp.pkt_untaged_cnt;
1146 txsc->stats.InPktsUntagged += rx_rsp.pkt_untaged_cnt;
1148 list_for_each_entry(rxsc, &cfg->rxsc_list, entry) {
1149 cn10k_mcs_sc_stats(pfvf, rxsc->hw_sc_id, &sc_rsp, MCS_RX, true);
1151 rxsc->stats.InOctetsValidated += sc_rsp.octet_validate_cnt;
1152 rxsc->stats.InOctetsDecrypted += sc_rsp.octet_decrypt_cnt;
1154 rxsc->stats.InPktsInvalid += sc_rsp.pkt_invalid_cnt;
1155 rxsc->stats.InPktsNotValid += sc_rsp.pkt_notvalid_cnt;
1157 if (txsc->last_replay_protect)
1158 rxsc->stats.InPktsLate += sc_rsp.pkt_late_cnt;
1160 rxsc->stats.InPktsDelayed += sc_rsp.pkt_late_cnt;
1162 if (txsc->last_validate_frames == MACSEC_VALIDATE_DISABLED)
1163 rxsc->stats.InPktsUnchecked += sc_rsp.pkt_unchecked_cnt;
1165 rxsc->stats.InPktsOK += sc_rsp.pkt_unchecked_cnt;
1168 txsc->last_validate_frames = secy->validate_frames;
1169 txsc->last_replay_protect = secy->replay_protect;
1172 static int cn10k_mdo_open(struct macsec_context *ctx)
1174 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1175 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1176 struct macsec_secy *secy = ctx->secy;
1177 struct macsec_tx_sa *sw_tx_sa;
1178 struct cn10k_mcs_txsc *txsc;
1182 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1186 sa_num = txsc->encoding_sa;
1187 sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[sa_num]);
1189 err = cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, sw_tx_sa, sa_num);
1193 return cn10k_mcs_secy_rx_cfg(pfvf, secy, txsc->hw_secy_id_rx);
1196 static int cn10k_mdo_stop(struct macsec_context *ctx)
1198 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1199 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1200 struct cn10k_mcs_txsc *txsc;
1203 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1207 err = cn10k_mcs_ena_dis_flowid(pfvf, txsc->hw_flow_id, false, MCS_TX);
1211 return cn10k_mcs_disable_rxscs(pfvf, ctx->secy, false);
1214 static int cn10k_mdo_add_secy(struct macsec_context *ctx)
1216 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1217 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1218 struct macsec_secy *secy = ctx->secy;
1219 struct cn10k_mcs_txsc *txsc;
1221 if (secy->icv_len != MACSEC_DEFAULT_ICV_LEN)
1224 txsc = cn10k_mcs_create_txsc(pfvf);
1228 txsc->sw_secy = secy;
1229 txsc->encoding_sa = secy->tx_sc.encoding_sa;
1230 txsc->last_validate_frames = secy->validate_frames;
1231 txsc->last_replay_protect = secy->replay_protect;
1232 txsc->vlan_dev = is_vlan_dev(ctx->netdev);
1234 list_add(&txsc->entry, &cfg->txsc_list);
1236 if (netif_running(secy->netdev))
1237 return cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, NULL, 0);
1242 static int cn10k_mdo_upd_secy(struct macsec_context *ctx)
1244 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1245 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1246 struct macsec_secy *secy = ctx->secy;
1247 struct macsec_tx_sa *sw_tx_sa;
1248 struct cn10k_mcs_txsc *txsc;
1253 txsc = cn10k_mcs_get_txsc(cfg, secy);
1257 /* Encoding SA got changed */
1258 if (txsc->encoding_sa != secy->tx_sc.encoding_sa) {
1259 txsc->encoding_sa = secy->tx_sc.encoding_sa;
1260 sa_num = txsc->encoding_sa;
1261 sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[sa_num]);
1262 active = sw_tx_sa ? sw_tx_sa->active : false;
1263 cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc, sa_num, active);
1266 if (netif_running(secy->netdev)) {
1267 cn10k_mcs_sync_stats(pfvf, secy, txsc);
1269 err = cn10k_mcs_secy_tx_cfg(pfvf, secy, txsc, NULL, 0);
1277 static int cn10k_mdo_del_secy(struct macsec_context *ctx)
1279 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1280 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1281 struct cn10k_mcs_txsc *txsc;
1283 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1287 cn10k_mcs_ena_dis_flowid(pfvf, txsc->hw_flow_id, false, MCS_TX);
1288 cn10k_mcs_disable_rxscs(pfvf, ctx->secy, true);
1289 cn10k_mcs_delete_txsc(pfvf, txsc);
1290 list_del(&txsc->entry);
1296 static int cn10k_mdo_add_txsa(struct macsec_context *ctx)
1298 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1299 struct macsec_tx_sa *sw_tx_sa = ctx->sa.tx_sa;
1300 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1301 struct macsec_secy *secy = ctx->secy;
1302 u8 sa_num = ctx->sa.assoc_num;
1303 struct cn10k_mcs_txsc *txsc;
1306 txsc = cn10k_mcs_get_txsc(cfg, secy);
1310 if (sa_num >= CN10K_MCS_SA_PER_SC)
1313 if (cn10k_mcs_alloc_txsa(pfvf, &txsc->hw_sa_id[sa_num]))
1316 memcpy(&txsc->sa_key[sa_num], ctx->sa.key, secy->key_len);
1317 memcpy(&txsc->salt[sa_num], sw_tx_sa->key.salt.bytes, MACSEC_SALT_LEN);
1318 txsc->ssci[sa_num] = sw_tx_sa->ssci;
1320 txsc->sa_bmap |= 1 << sa_num;
1322 if (netif_running(secy->netdev)) {
1323 err = cn10k_mcs_write_tx_sa_plcy(pfvf, secy, txsc, sa_num);
1327 err = cn10k_write_tx_sa_pn(pfvf, txsc, sa_num,
1332 err = cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc,
1333 sa_num, sw_tx_sa->active);
1341 static int cn10k_mdo_upd_txsa(struct macsec_context *ctx)
1343 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1344 struct macsec_tx_sa *sw_tx_sa = ctx->sa.tx_sa;
1345 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1346 struct macsec_secy *secy = ctx->secy;
1347 u8 sa_num = ctx->sa.assoc_num;
1348 struct cn10k_mcs_txsc *txsc;
1351 txsc = cn10k_mcs_get_txsc(cfg, secy);
1355 if (sa_num >= CN10K_MCS_SA_PER_SC)
1358 if (netif_running(secy->netdev)) {
1359 /* Keys cannot be changed after creation */
1360 if (ctx->sa.update_pn) {
1361 err = cn10k_write_tx_sa_pn(pfvf, txsc, sa_num,
1367 err = cn10k_mcs_link_tx_sa2sc(pfvf, secy, txsc,
1368 sa_num, sw_tx_sa->active);
1376 static int cn10k_mdo_del_txsa(struct macsec_context *ctx)
1378 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1379 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1380 u8 sa_num = ctx->sa.assoc_num;
1381 struct cn10k_mcs_txsc *txsc;
1383 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1387 if (sa_num >= CN10K_MCS_SA_PER_SC)
1390 cn10k_mcs_free_txsa(pfvf, txsc->hw_sa_id[sa_num]);
1391 txsc->sa_bmap &= ~(1 << sa_num);
1396 static int cn10k_mdo_add_rxsc(struct macsec_context *ctx)
1398 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1399 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1400 struct macsec_secy *secy = ctx->secy;
1401 struct cn10k_mcs_rxsc *rxsc;
1402 struct cn10k_mcs_txsc *txsc;
1405 txsc = cn10k_mcs_get_txsc(cfg, secy);
1409 rxsc = cn10k_mcs_create_rxsc(pfvf);
1413 rxsc->sw_secy = ctx->secy;
1414 rxsc->sw_rxsc = ctx->rx_sc;
1415 list_add(&rxsc->entry, &cfg->rxsc_list);
1417 if (netif_running(secy->netdev)) {
1418 err = cn10k_mcs_write_rx_flowid(pfvf, rxsc, txsc->hw_secy_id_rx);
1422 err = cn10k_mcs_write_sc_cam(pfvf, rxsc, txsc->hw_secy_id_rx);
1430 static int cn10k_mdo_upd_rxsc(struct macsec_context *ctx)
1432 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1433 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1434 struct macsec_secy *secy = ctx->secy;
1435 bool enable = ctx->rx_sc->active;
1436 struct cn10k_mcs_rxsc *rxsc;
1438 rxsc = cn10k_mcs_get_rxsc(cfg, secy, ctx->rx_sc);
1442 if (netif_running(secy->netdev))
1443 return cn10k_mcs_ena_dis_flowid(pfvf, rxsc->hw_flow_id,
1449 static int cn10k_mdo_del_rxsc(struct macsec_context *ctx)
1451 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1452 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1453 struct cn10k_mcs_rxsc *rxsc;
1455 rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, ctx->rx_sc);
1459 cn10k_mcs_ena_dis_flowid(pfvf, rxsc->hw_flow_id, false, MCS_RX);
1460 cn10k_mcs_delete_rxsc(pfvf, rxsc);
1461 list_del(&rxsc->entry);
1467 static int cn10k_mdo_add_rxsa(struct macsec_context *ctx)
1469 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1470 struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;
1471 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1472 struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;
1473 struct macsec_secy *secy = ctx->secy;
1474 bool sa_in_use = rx_sa->active;
1475 u8 sa_num = ctx->sa.assoc_num;
1476 struct cn10k_mcs_rxsc *rxsc;
1479 rxsc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);
1483 if (sa_num >= CN10K_MCS_SA_PER_SC)
1486 if (cn10k_mcs_alloc_rxsa(pfvf, &rxsc->hw_sa_id[sa_num]))
1489 memcpy(&rxsc->sa_key[sa_num], ctx->sa.key, ctx->secy->key_len);
1490 memcpy(&rxsc->salt[sa_num], rx_sa->key.salt.bytes, MACSEC_SALT_LEN);
1491 rxsc->ssci[sa_num] = rx_sa->ssci;
1493 rxsc->sa_bmap |= 1 << sa_num;
1495 if (netif_running(secy->netdev)) {
1496 err = cn10k_mcs_write_rx_sa_plcy(pfvf, secy, rxsc,
1501 err = cn10k_mcs_write_rx_sa_pn(pfvf, rxsc, sa_num,
1510 static int cn10k_mdo_upd_rxsa(struct macsec_context *ctx)
1512 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1513 struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;
1514 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1515 struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;
1516 struct macsec_secy *secy = ctx->secy;
1517 bool sa_in_use = rx_sa->active;
1518 u8 sa_num = ctx->sa.assoc_num;
1519 struct cn10k_mcs_rxsc *rxsc;
1522 rxsc = cn10k_mcs_get_rxsc(cfg, secy, sw_rx_sc);
1526 if (sa_num >= CN10K_MCS_SA_PER_SC)
1529 if (netif_running(secy->netdev)) {
1530 err = cn10k_mcs_write_rx_sa_plcy(pfvf, secy, rxsc, sa_num, sa_in_use);
1534 if (!ctx->sa.update_pn)
1537 err = cn10k_mcs_write_rx_sa_pn(pfvf, rxsc, sa_num,
1546 static int cn10k_mdo_del_rxsa(struct macsec_context *ctx)
1548 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1549 struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;
1550 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1551 u8 sa_num = ctx->sa.assoc_num;
1552 struct cn10k_mcs_rxsc *rxsc;
1554 rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, sw_rx_sc);
1558 if (sa_num >= CN10K_MCS_SA_PER_SC)
1561 cn10k_mcs_write_rx_sa_plcy(pfvf, ctx->secy, rxsc, sa_num, false);
1562 cn10k_mcs_free_rxsa(pfvf, rxsc->hw_sa_id[sa_num]);
1564 rxsc->sa_bmap &= ~(1 << sa_num);
1569 static int cn10k_mdo_get_dev_stats(struct macsec_context *ctx)
1571 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1572 struct mcs_secy_stats tx_rsp = { 0 }, rx_rsp = { 0 };
1573 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1574 struct macsec_secy *secy = ctx->secy;
1575 struct cn10k_mcs_txsc *txsc;
1577 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1581 cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_tx, &tx_rsp, MCS_TX, false);
1582 ctx->stats.dev_stats->OutPktsUntagged = tx_rsp.pkt_untagged_cnt;
1583 ctx->stats.dev_stats->OutPktsTooLong = tx_rsp.pkt_toolong_cnt;
1585 cn10k_mcs_secy_stats(pfvf, txsc->hw_secy_id_rx, &rx_rsp, MCS_RX, true);
1586 txsc->stats.InPktsBadTag += rx_rsp.pkt_badtag_cnt;
1587 txsc->stats.InPktsUnknownSCI += rx_rsp.pkt_nosa_cnt;
1588 txsc->stats.InPktsNoSCI += rx_rsp.pkt_nosaerror_cnt;
1589 if (secy->validate_frames == MACSEC_VALIDATE_STRICT)
1590 txsc->stats.InPktsNoTag += rx_rsp.pkt_untaged_cnt;
1592 txsc->stats.InPktsUntagged += rx_rsp.pkt_untaged_cnt;
1593 txsc->stats.InPktsOverrun = 0;
1595 ctx->stats.dev_stats->InPktsNoTag = txsc->stats.InPktsNoTag;
1596 ctx->stats.dev_stats->InPktsUntagged = txsc->stats.InPktsUntagged;
1597 ctx->stats.dev_stats->InPktsBadTag = txsc->stats.InPktsBadTag;
1598 ctx->stats.dev_stats->InPktsUnknownSCI = txsc->stats.InPktsUnknownSCI;
1599 ctx->stats.dev_stats->InPktsNoSCI = txsc->stats.InPktsNoSCI;
1600 ctx->stats.dev_stats->InPktsOverrun = txsc->stats.InPktsOverrun;
1605 static int cn10k_mdo_get_tx_sc_stats(struct macsec_context *ctx)
1607 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1608 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1609 struct mcs_sc_stats rsp = { 0 };
1610 struct cn10k_mcs_txsc *txsc;
1612 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1616 cn10k_mcs_sc_stats(pfvf, txsc->hw_sc_id, &rsp, MCS_TX, false);
1618 ctx->stats.tx_sc_stats->OutPktsProtected = rsp.pkt_protected_cnt;
1619 ctx->stats.tx_sc_stats->OutPktsEncrypted = rsp.pkt_encrypt_cnt;
1620 ctx->stats.tx_sc_stats->OutOctetsProtected = rsp.octet_protected_cnt;
1621 ctx->stats.tx_sc_stats->OutOctetsEncrypted = rsp.octet_encrypt_cnt;
1626 static int cn10k_mdo_get_tx_sa_stats(struct macsec_context *ctx)
1628 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1629 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1630 struct mcs_sa_stats rsp = { 0 };
1631 u8 sa_num = ctx->sa.assoc_num;
1632 struct cn10k_mcs_txsc *txsc;
1634 txsc = cn10k_mcs_get_txsc(cfg, ctx->secy);
1638 if (sa_num >= CN10K_MCS_SA_PER_SC)
1641 cn10k_mcs_sa_stats(pfvf, txsc->hw_sa_id[sa_num], &rsp, MCS_TX, false);
1643 ctx->stats.tx_sa_stats->OutPktsProtected = rsp.pkt_protected_cnt;
1644 ctx->stats.tx_sa_stats->OutPktsEncrypted = rsp.pkt_encrypt_cnt;
1649 static int cn10k_mdo_get_rx_sc_stats(struct macsec_context *ctx)
1651 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1652 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1653 struct macsec_secy *secy = ctx->secy;
1654 struct mcs_sc_stats rsp = { 0 };
1655 struct cn10k_mcs_rxsc *rxsc;
1657 rxsc = cn10k_mcs_get_rxsc(cfg, secy, ctx->rx_sc);
1661 cn10k_mcs_sc_stats(pfvf, rxsc->hw_sc_id, &rsp, MCS_RX, true);
1663 rxsc->stats.InOctetsValidated += rsp.octet_validate_cnt;
1664 rxsc->stats.InOctetsDecrypted += rsp.octet_decrypt_cnt;
1666 rxsc->stats.InPktsInvalid += rsp.pkt_invalid_cnt;
1667 rxsc->stats.InPktsNotValid += rsp.pkt_notvalid_cnt;
1669 if (secy->replay_protect)
1670 rxsc->stats.InPktsLate += rsp.pkt_late_cnt;
1672 rxsc->stats.InPktsDelayed += rsp.pkt_late_cnt;
1674 if (secy->validate_frames == MACSEC_VALIDATE_DISABLED)
1675 rxsc->stats.InPktsUnchecked += rsp.pkt_unchecked_cnt;
1677 rxsc->stats.InPktsOK += rsp.pkt_unchecked_cnt;
1679 ctx->stats.rx_sc_stats->InOctetsValidated = rxsc->stats.InOctetsValidated;
1680 ctx->stats.rx_sc_stats->InOctetsDecrypted = rxsc->stats.InOctetsDecrypted;
1681 ctx->stats.rx_sc_stats->InPktsInvalid = rxsc->stats.InPktsInvalid;
1682 ctx->stats.rx_sc_stats->InPktsNotValid = rxsc->stats.InPktsNotValid;
1683 ctx->stats.rx_sc_stats->InPktsLate = rxsc->stats.InPktsLate;
1684 ctx->stats.rx_sc_stats->InPktsDelayed = rxsc->stats.InPktsDelayed;
1685 ctx->stats.rx_sc_stats->InPktsUnchecked = rxsc->stats.InPktsUnchecked;
1686 ctx->stats.rx_sc_stats->InPktsOK = rxsc->stats.InPktsOK;
1691 static int cn10k_mdo_get_rx_sa_stats(struct macsec_context *ctx)
1693 struct otx2_nic *pfvf = macsec_netdev_priv(ctx->netdev);
1694 struct macsec_rx_sc *sw_rx_sc = ctx->sa.rx_sa->sc;
1695 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1696 struct mcs_sa_stats rsp = { 0 };
1697 u8 sa_num = ctx->sa.assoc_num;
1698 struct cn10k_mcs_rxsc *rxsc;
1700 rxsc = cn10k_mcs_get_rxsc(cfg, ctx->secy, sw_rx_sc);
1704 if (sa_num >= CN10K_MCS_SA_PER_SC)
1707 cn10k_mcs_sa_stats(pfvf, rxsc->hw_sa_id[sa_num], &rsp, MCS_RX, false);
1709 ctx->stats.rx_sa_stats->InPktsOK = rsp.pkt_ok_cnt;
1710 ctx->stats.rx_sa_stats->InPktsInvalid = rsp.pkt_invalid_cnt;
1711 ctx->stats.rx_sa_stats->InPktsNotValid = rsp.pkt_notvalid_cnt;
1712 ctx->stats.rx_sa_stats->InPktsNotUsingSA = rsp.pkt_nosaerror_cnt;
1713 ctx->stats.rx_sa_stats->InPktsUnusedSA = rsp.pkt_nosa_cnt;
1718 static const struct macsec_ops cn10k_mcs_ops = {
1719 .mdo_dev_open = cn10k_mdo_open,
1720 .mdo_dev_stop = cn10k_mdo_stop,
1721 .mdo_add_secy = cn10k_mdo_add_secy,
1722 .mdo_upd_secy = cn10k_mdo_upd_secy,
1723 .mdo_del_secy = cn10k_mdo_del_secy,
1724 .mdo_add_rxsc = cn10k_mdo_add_rxsc,
1725 .mdo_upd_rxsc = cn10k_mdo_upd_rxsc,
1726 .mdo_del_rxsc = cn10k_mdo_del_rxsc,
1727 .mdo_add_rxsa = cn10k_mdo_add_rxsa,
1728 .mdo_upd_rxsa = cn10k_mdo_upd_rxsa,
1729 .mdo_del_rxsa = cn10k_mdo_del_rxsa,
1730 .mdo_add_txsa = cn10k_mdo_add_txsa,
1731 .mdo_upd_txsa = cn10k_mdo_upd_txsa,
1732 .mdo_del_txsa = cn10k_mdo_del_txsa,
1733 .mdo_get_dev_stats = cn10k_mdo_get_dev_stats,
1734 .mdo_get_tx_sc_stats = cn10k_mdo_get_tx_sc_stats,
1735 .mdo_get_tx_sa_stats = cn10k_mdo_get_tx_sa_stats,
1736 .mdo_get_rx_sc_stats = cn10k_mdo_get_rx_sc_stats,
1737 .mdo_get_rx_sa_stats = cn10k_mdo_get_rx_sa_stats,
1740 void cn10k_handle_mcs_event(struct otx2_nic *pfvf, struct mcs_intr_info *event)
1742 struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
1743 struct macsec_tx_sa *sw_tx_sa = NULL;
1744 struct macsec_secy *secy = NULL;
1745 struct cn10k_mcs_txsc *txsc;
1748 if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))
1751 if (!(event->intr_mask & MCS_CPM_TX_PACKET_XPN_EQ0_INT))
1754 /* Find the SecY to which the expired hardware SA is mapped */
1755 list_for_each_entry(txsc, &cfg->txsc_list, entry) {
1756 for (an = 0; an < CN10K_MCS_SA_PER_SC; an++)
1757 if (txsc->hw_sa_id[an] == event->sa_id) {
1758 secy = txsc->sw_secy;
1759 sw_tx_sa = rcu_dereference_bh(secy->tx_sc.sa[an]);
1763 if (secy && sw_tx_sa)
1764 macsec_pn_wrapped(secy, sw_tx_sa);
1767 int cn10k_mcs_init(struct otx2_nic *pfvf)
1769 struct mbox *mbox = &pfvf->mbox;
1770 struct cn10k_mcs_cfg *cfg;
1771 struct mcs_intr_cfg *req;
1773 if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))
1776 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1780 INIT_LIST_HEAD(&cfg->txsc_list);
1781 INIT_LIST_HEAD(&cfg->rxsc_list);
1782 pfvf->macsec_cfg = cfg;
1784 pfvf->netdev->features |= NETIF_F_HW_MACSEC;
1785 pfvf->netdev->macsec_ops = &cn10k_mcs_ops;
1787 mutex_lock(&mbox->lock);
1789 req = otx2_mbox_alloc_msg_mcs_intr_cfg(mbox);
1793 req->intr_mask = MCS_CPM_TX_PACKET_XPN_EQ0_INT;
1795 if (otx2_sync_mbox_msg(mbox))
1798 mutex_unlock(&mbox->lock);
1802 dev_err(pfvf->dev, "Cannot notify PN wrapped event\n");
1803 mutex_unlock(&mbox->lock);
1807 void cn10k_mcs_free(struct otx2_nic *pfvf)
1809 if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))
1812 cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY, 0, true);
1813 cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY, 0, true);
1814 kfree(pfvf->macsec_cfg);
1815 pfvf->macsec_cfg = NULL;