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