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