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