1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 Marvell. 3 */ 4 5 /** 6 * @file rte_pmd_cnxk.h 7 * CNXK PMD specific functions. 8 * 9 **/ 10 11 #ifndef _PMD_CNXK_H_ 12 #define _PMD_CNXK_H_ 13 14 #include <rte_compat.h> 15 #include <rte_ethdev.h> 16 #include <rte_ether.h> 17 #include <rte_security.h> 18 19 /** Algorithm type to be used with security action to 20 * calculate SA_index 21 */ 22 enum rte_pmd_cnxk_sec_action_alg { 23 /** No swizzling of SPI bits into SA index. 24 * SA_index is from SA_XOR if enabled. 25 */ 26 RTE_PMD_CNXK_SEC_ACTION_ALG0, 27 /** SPI<31:28> has 4 upper bits which segment the sequence number space. 28 * Initial SA_index is from SA_XOR if enabled. 29 * SA_alg = { 4'b0, SA_mcam[27:0] + SPI[31:28]} 30 */ 31 RTE_PMD_CNXK_SEC_ACTION_ALG1, 32 /** SPI<27:25> segment the sequence number space. 33 * Initial SA_index is from SA_XOR if enabled. 34 * SA_alg = { 7'b0, SA_mcam[24:0] + SPI[27:25]} 35 */ 36 RTE_PMD_CNXK_SEC_ACTION_ALG2, 37 /** SPI<28:25> segment the sequence number space. 38 * Initial SA_index is from SA_XOR if enabled. 39 * SA_alg = { 7'b0, SA_mcam[24:0] + SPI[28:25]} 40 */ 41 RTE_PMD_CNXK_SEC_ACTION_ALG3, 42 /** The inbound SPI maybe "random", therefore we want the MCAM to be 43 * capable of remapping the SPI to an arbitrary SA_index. 44 * SPI to SA is done using a lookup in NIX/NPC cam entry with key as 45 * SPI, MATCH_ID, LFID. 46 */ 47 RTE_PMD_CNXK_SEC_ACTION_ALG4, 48 }; 49 50 /** CPT queue type for obtaining queue hardware statistics. */ 51 enum rte_pmd_cnxk_cpt_q_stats_type { 52 /** Type to get Inline Device queue(s) statistics */ 53 RTE_PMD_CNXK_CPT_Q_STATS_INL_DEV, 54 /** Type to get Inline Inbound queue which is attached to kernel device 55 * statistics. 56 */ 57 RTE_PMD_CNXK_CPT_Q_STATS_KERNEL, 58 /** Type to get CPT queue which is attached to ethdev statistics */ 59 RTE_PMD_CNXK_CPT_Q_STATS_ETHDEV, 60 }; 61 62 /** CPT queue hardware statistics */ 63 struct rte_pmd_cnxk_cpt_q_stats { 64 /** Encrypted packet count */ 65 uint64_t enc_pkts; 66 /** Encrypted byte count */ 67 uint64_t enc_bytes; 68 /** Decrypted packet count */ 69 uint64_t dec_pkts; 70 /** Decrypted byte count */ 71 uint64_t dec_bytes; 72 }; 73 74 struct rte_pmd_cnxk_sec_action { 75 /** Used as lookup result for ALG3 */ 76 uint32_t sa_index; 77 /** When true XOR initial SA_INDEX with SA_HI/SA_LO to get SA_MCAM */ 78 bool sa_xor; 79 /** SA_hi and SA_lo values for xor */ 80 uint16_t sa_hi, sa_lo; 81 /** Determines alg to be applied post SA_MCAM computation with/without 82 * XOR. 83 */ 84 enum rte_pmd_cnxk_sec_action_alg alg; 85 }; 86 87 #define RTE_PMD_CNXK_CTX_MAX_CKEY_LEN 32 88 #define RTE_PMD_CNXK_CTX_MAX_OPAD_IPAD_LEN 128 89 90 /** Anti reply window size supported */ 91 #define RTE_PMD_CNXK_AR_WIN_SIZE_MIN 64 92 #define RTE_PMD_CNXK_AR_WIN_SIZE_MAX 4096 93 #define RTE_PMD_CNXK_LOG_MIN_AR_WIN_SIZE_M1 5 94 95 /** u64 array size to fit anti replay window bits */ 96 #define RTE_PMD_CNXK_AR_WINBITS_SZ (RTE_ALIGN_CEIL(RTE_PMD_CNXK_AR_WIN_SIZE_MAX, 64) / 64) 97 98 /** Outer header info for Inbound or Outbound */ 99 union rte_pmd_cnxk_ipsec_outer_ip_hdr { 100 struct { 101 /** IPv4 destination */ 102 uint32_t dst_addr; 103 /** IPv4 source */ 104 uint32_t src_addr; 105 } ipv4; 106 struct { 107 /** IPv6 source */ 108 uint8_t src_addr[16]; 109 /** IPv6 destination */ 110 uint8_t dst_addr[16]; 111 } ipv6; 112 }; 113 114 /** Inbound IPsec context update region */ 115 struct rte_pmd_cnxk_ipsec_inb_ctx_update_reg { 116 /** Highest sequence number received */ 117 uint64_t ar_base; 118 /** Valid bit for 64-bit words of replay window */ 119 uint64_t ar_valid_mask; 120 /** Hard life for SA */ 121 uint64_t hard_life; 122 /** Soft life for SA */ 123 uint64_t soft_life; 124 /** MIB octets */ 125 uint64_t mib_octs; 126 /** MIB packets */ 127 uint64_t mib_pkts; 128 /** AR window bits */ 129 uint64_t ar_winbits[RTE_PMD_CNXK_AR_WINBITS_SZ]; 130 }; 131 132 /** Outbound IPsec IV data */ 133 union rte_pmd_cnxk_ipsec_outb_iv { 134 uint64_t u64[2]; 135 /** IV debug - 16B*/ 136 uint8_t iv_dbg[16]; 137 struct { 138 /** IV debug - 8B */ 139 uint8_t iv_dbg1[4]; 140 /** Salt */ 141 uint8_t salt[4]; 142 143 uint32_t rsvd; 144 /** IV debug - 8B */ 145 uint8_t iv_dbg2[4]; 146 } s; 147 }; 148 149 /** Outbound IPsec context update region */ 150 struct rte_pmd_cnxk_ipsec_outb_ctx_update_reg { 151 union { 152 struct { 153 uint64_t reserved_0_2 : 3; 154 uint64_t address : 57; 155 uint64_t mode : 4; 156 } s; 157 uint64_t u64; 158 } err_ctl; 159 160 uint64_t esn_val; 161 uint64_t hard_life; 162 uint64_t soft_life; 163 uint64_t mib_octs; 164 uint64_t mib_pkts; 165 }; 166 167 /** 168 * Inbound IPsec SA 169 */ 170 struct rte_pmd_cnxk_ipsec_inb_sa { 171 /** Word0 */ 172 union { 173 struct { 174 /** AR window size */ 175 uint64_t ar_win : 3; 176 /** Hard life enable */ 177 uint64_t hard_life_dec : 1; 178 /** Soft life enable */ 179 uint64_t soft_life_dec : 1; 180 181 /** Count global octets */ 182 uint64_t count_glb_octets : 1; 183 /** Count global pkts */ 184 uint64_t count_glb_pkts : 1; 185 /** Count bytes */ 186 uint64_t count_mib_bytes : 1; 187 188 /** Count pkts */ 189 uint64_t count_mib_pkts : 1; 190 /** HW context offset */ 191 uint64_t hw_ctx_off : 7; 192 193 /** Context ID */ 194 uint64_t ctx_id : 16; 195 196 /** Original packet free absolute */ 197 uint64_t orig_pkt_fabs : 1; 198 /** Original packet free */ 199 uint64_t orig_pkt_free : 1; 200 /** PKIND for second pass */ 201 uint64_t pkind : 6; 202 203 uint64_t rsvd0 : 1; 204 /** Ether type overwrite */ 205 uint64_t et_ovrwr : 1; 206 /** Packet output type */ 207 uint64_t pkt_output : 2; 208 /** Packet format type */ 209 uint64_t pkt_format : 1; 210 /** Defrag option */ 211 uint64_t defrag_opt : 2; 212 /** Reserved for X2P dest */ 213 uint64_t x2p_dst : 1; 214 215 /** Context push size */ 216 uint64_t ctx_push_size : 7; 217 uint64_t rsvd1 : 1; 218 219 /** Context header size */ 220 uint64_t ctx_hdr_size : 2; 221 /** AOP enable */ 222 uint64_t aop_valid : 1; 223 uint64_t rsvd2 : 1; 224 /** Context size */ 225 uint64_t ctx_size : 4; 226 } s; 227 uint64_t u64; 228 } w0; 229 230 /** Word1 */ 231 union { 232 struct { 233 /** Original packet aura */ 234 uint64_t orig_pkt_aura : 20; 235 uint64_t rsvd3 : 4; 236 /** Original packet free offset */ 237 uint64_t orig_pkt_foff : 8; 238 /** SA cookie */ 239 uint64_t cookie : 32; 240 } s; 241 uint64_t u64; 242 } w1; 243 244 /** Word 2 */ 245 union { 246 struct { 247 /** SA valid */ 248 uint64_t valid : 1; 249 /** SA direction */ 250 uint64_t dir : 1; 251 uint64_t rsvd11 : 1; 252 uint64_t rsvd4 : 1; 253 /** IPsec mode */ 254 uint64_t ipsec_mode : 1; 255 /** IPsec protocol */ 256 uint64_t ipsec_protocol : 1; 257 /** AES key length */ 258 uint64_t aes_key_len : 2; 259 260 /** Encryption algo */ 261 uint64_t enc_type : 3; 262 /** Soft life and hard life unit */ 263 uint64_t life_unit : 1; 264 /** Authentication algo */ 265 uint64_t auth_type : 4; 266 267 /** Encapsulation type */ 268 uint64_t encap_type : 2; 269 /** Ether type override enable */ 270 uint64_t et_ovrwr_ddr_en : 1; 271 /** ESN enable */ 272 uint64_t esn_en : 1; 273 /** Transport mode L4 checksum incrementally update */ 274 uint64_t tport_l4_incr_csum : 1; 275 /** Outer IP header verification */ 276 uint64_t ip_hdr_verify : 2; 277 /** UDP enacapsulation ports verification */ 278 uint64_t udp_ports_verify : 1; 279 280 /** Return 64B of L2/L3 header on error */ 281 uint64_t l3hdr_on_err : 1; 282 uint64_t rsvd6 : 6; 283 uint64_t rsvd12 : 1; 284 285 /** SPI */ 286 uint64_t spi : 32; 287 } s; 288 uint64_t u64; 289 } w2; 290 291 /** Word3 */ 292 uint64_t rsvd7; 293 294 /** Word4 - Word7 */ 295 uint8_t cipher_key[RTE_PMD_CNXK_CTX_MAX_CKEY_LEN]; 296 297 /** Word8 - Word9 */ 298 union { 299 struct { 300 uint32_t rsvd8; 301 /** IV salt */ 302 uint8_t salt[4]; 303 } s; 304 uint64_t u64; 305 } w8; 306 uint64_t rsvd9; 307 308 /** Word10 */ 309 union { 310 struct { 311 uint64_t rsvd10 : 32; 312 /** UDP encapsulation source port */ 313 uint64_t udp_src_port : 16; 314 /** UDP encapsulation destination port */ 315 uint64_t udp_dst_port : 16; 316 } s; 317 uint64_t u64; 318 } w10; 319 320 /** Word11 - Word14 */ 321 union rte_pmd_cnxk_ipsec_outer_ip_hdr outer_hdr; 322 323 /** Word15 - Word30 */ 324 uint8_t hmac_opad_ipad[RTE_PMD_CNXK_CTX_MAX_OPAD_IPAD_LEN]; 325 326 /** Word31 - Word100 */ 327 struct rte_pmd_cnxk_ipsec_inb_ctx_update_reg ctx; 328 }; 329 330 /** 331 * Outbound IPsec SA 332 */ 333 struct rte_pmd_cnxk_ipsec_outb_sa { 334 /** Word0 */ 335 union { 336 struct { 337 /** ESN enable */ 338 uint64_t esn_en : 1; 339 /** IP ID generation type */ 340 uint64_t ip_id : 1; 341 uint64_t rsvd0 : 1; 342 /** Hard life enable */ 343 uint64_t hard_life_dec : 1; 344 /** Soft life enable */ 345 uint64_t soft_life_dec : 1; 346 347 /** Count global octets */ 348 uint64_t count_glb_octets : 1; 349 /** Count global pkts */ 350 uint64_t count_glb_pkts : 1; 351 /** Count bytes */ 352 uint64_t count_mib_bytes : 1; 353 354 /** Count pkts */ 355 uint64_t count_mib_pkts : 1; 356 /** HW context offset */ 357 uint64_t hw_ctx_off : 7; 358 359 /** Context ID */ 360 uint64_t ctx_id : 16; 361 uint64_t rsvd1 : 16; 362 363 /** Context push size */ 364 uint64_t ctx_push_size : 7; 365 uint64_t rsvd2 : 1; 366 367 /** Context header size */ 368 uint64_t ctx_hdr_size : 2; 369 /** AOP enable */ 370 uint64_t aop_valid : 1; 371 uint64_t rsvd3 : 1; 372 /** Context size */ 373 uint64_t ctx_size : 4; 374 } s; 375 uint64_t u64; 376 } w0; 377 378 /** Word1 */ 379 union { 380 struct { 381 uint64_t rsvd4 : 32; 382 /** SA cookie */ 383 uint64_t cookie : 32; 384 } s; 385 uint64_t u64; 386 } w1; 387 388 /** Word 2 */ 389 union { 390 struct { 391 /** SA valid */ 392 uint64_t valid : 1; 393 /** SA direction */ 394 uint64_t dir : 1; 395 uint64_t rsvd11 : 1; 396 uint64_t rsvd5 : 1; 397 /** IPsec mode */ 398 uint64_t ipsec_mode : 1; 399 /** IPsec protocol */ 400 uint64_t ipsec_protocol : 1; 401 402 /** AES key length */ 403 uint64_t aes_key_len : 2; 404 405 /** Encryption algo */ 406 uint64_t enc_type : 3; 407 /** Soft life and hard life unit */ 408 uint64_t life_unit : 1; 409 /** Authentication algo */ 410 uint64_t auth_type : 4; 411 412 /** Encapsulation type */ 413 uint64_t encap_type : 2; 414 /** DF source */ 415 uint64_t ipv4_df_src_or_ipv6_flw_lbl_src : 1; 416 /** DSCP source */ 417 uint64_t dscp_src : 1; 418 /** IV source */ 419 uint64_t iv_src : 2; 420 /** IPID value in outer header */ 421 uint64_t ipid_gen : 1; 422 uint64_t rsvd6 : 1; 423 424 uint64_t rsvd7 : 7; 425 uint64_t rsvd12 : 1; 426 427 /** SPI */ 428 uint64_t spi : 32; 429 } s; 430 uint64_t u64; 431 } w2; 432 433 /** Word3 */ 434 uint64_t rsvd8; 435 436 /** Word4 - Word7 */ 437 uint8_t cipher_key[RTE_PMD_CNXK_CTX_MAX_CKEY_LEN]; 438 439 /** Word8 - Word9 */ 440 union rte_pmd_cnxk_ipsec_outb_iv iv; 441 442 /** Word10 */ 443 union { 444 struct { 445 uint64_t rsvd9 : 4; 446 /** Outer header IPv4 DF or IPv6 flow label */ 447 uint64_t ipv4_df_or_ipv6_flw_lbl : 20; 448 449 /** DSCP for outer header */ 450 uint64_t dscp : 6; 451 uint64_t rsvd10 : 2; 452 453 /** UDP encapsulation destination port */ 454 uint64_t udp_dst_port : 16; 455 456 /** UDP encapsulation source port */ 457 uint64_t udp_src_port : 16; 458 } s; 459 uint64_t u64; 460 } w10; 461 462 /** Word11 - Word14 */ 463 union rte_pmd_cnxk_ipsec_outer_ip_hdr outer_hdr; 464 465 /** Word15 - Word30 */ 466 uint8_t hmac_opad_ipad[RTE_PMD_CNXK_CTX_MAX_OPAD_IPAD_LEN]; 467 468 /** Word31 - Word36 */ 469 struct rte_pmd_cnxk_ipsec_outb_ctx_update_reg ctx; 470 }; 471 472 /** Inbound/Outbound IPsec SA */ 473 union rte_pmd_cnxk_ipsec_hw_sa { 474 /** Inbound SA */ 475 struct rte_pmd_cnxk_ipsec_inb_sa inb; 476 /** Outbound SA */ 477 struct rte_pmd_cnxk_ipsec_outb_sa outb; 478 }; 479 480 /** CPT HW result format */ 481 union rte_pmd_cnxk_cpt_res_s { 482 /** CN10K CPT result */ 483 struct rte_pmd_cpt_cn10k_res_s { 484 /** Completion code */ 485 uint64_t compcode : 7; 486 /** Done interrupt */ 487 uint64_t doneint : 1; 488 /** Microcode completion code */ 489 uint64_t uc_compcode : 8; 490 /** Result length */ 491 uint64_t rlen : 16; 492 /** SPI */ 493 uint64_t spi : 32; 494 495 /** Extended sequence number */ 496 uint64_t esn; 497 } cn10k; 498 499 /** CN9K CPT result */ 500 struct rte_pmd_cpt_cn9k_res_s { 501 /** Completion code */ 502 uint64_t compcode : 8; 503 /** Microcode completion code */ 504 uint64_t uc_compcode : 8; 505 /** Done interrupt */ 506 uint64_t doneint : 1; 507 uint64_t reserved_17_63 : 47; 508 509 uint64_t reserved_64_127; 510 } cn9k; 511 512 /** CPT RES */ 513 uint64_t u64[2]; 514 }; 515 516 /** Inline IPsec inbound queue configuration */ 517 struct rte_pmd_cnxk_ipsec_inb_cfg { 518 /** Param1 of PROCESS_INBOUND_IPSEC_PACKET as mentioned in the CPT 519 * microcode document. 520 */ 521 uint16_t param1; 522 /** Param2 of PROCESS_INBOUND_IPSEC_PACKET as mentioned in the CPT 523 * microcode document. 524 */ 525 uint16_t param2; 526 }; 527 528 /** Forward structure declaration for inline device queue. Applications obtain a pointer 529 * to this structure using the ``rte_pmd_cnxk_inl_dev_qptr_get`` API and use it to submit 530 * CPT instructions (cpt_inst_s) to the inline device via the 531 * ``rte_pmd_cnxk_inl_dev_submit`` API. 532 */ 533 struct rte_pmd_cnxk_inl_dev_q; 534 535 /** 536 * Read HW SA context from session. 537 * 538 * @param portid 539 * Port identifier of Ethernet device. 540 * @param sess 541 * Handle of the security session as void *. 542 * @param[out] data 543 * Destination pointer to copy SA context for application. 544 * @param len 545 * Length of SA context to copy into data parameter. 546 * @param inb 547 * Determines the type of specified SA. 548 * 549 * @return 550 * 0 on success, a negative errno value otherwise. 551 */ 552 __rte_experimental 553 int rte_pmd_cnxk_hw_sa_read(uint16_t portid, void *sess, union rte_pmd_cnxk_ipsec_hw_sa *data, 554 uint32_t len, bool inb); 555 /** 556 * Write HW SA context to session. 557 * 558 * @param portid 559 * Port identifier of Ethernet device. 560 * @param sess 561 * Handle of the security session as void *. 562 * @param[in] data 563 * Source data pointer from application to copy SA context into session. 564 * @param len 565 * Length of SA context to copy from data parameter. 566 * @param inb 567 * Determines the type of specified SA. 568 * 569 * @return 570 * 0 on success, a negative errno value otherwise. 571 */ 572 __rte_experimental 573 int rte_pmd_cnxk_hw_sa_write(uint16_t portid, void *sess, union rte_pmd_cnxk_ipsec_hw_sa *data, 574 uint32_t len, bool inb); 575 576 /** 577 * Get pointer to CPT result info for inline inbound processed pkt. 578 * 579 * It is recommended to use this API only when mbuf indicates packet 580 * was processed with inline IPsec and there was a failure with the same i.e 581 * mbuf->ol_flags indicates (RTE_MBUF_F_RX_SEC_OFFLOAD | RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED). 582 * 583 * @param mbuf 584 * Pointer to packet that was just received and was processed with Inline IPsec. 585 * 586 * @return 587 * - Pointer to mbuf location where `union rte_pmd_cnxk_cpt_res_s` is stored on success. 588 * - NULL on failure. 589 */ 590 __rte_experimental 591 union rte_pmd_cnxk_cpt_res_s *rte_pmd_cnxk_inl_ipsec_res(struct rte_mbuf *mbuf); 592 593 /** 594 * Get pointer to the Inline Inbound or Outbound SA table base. 595 * 596 * @param portid 597 * Port identifier of Ethernet device. 598 * @param inb 599 * Determines the type of SA base to be returned. 600 * When inb is true, the method returns the Inbound SA base. 601 * When inb is false, the method returns the Outbound SA base. 602 * 603 * @return 604 * Pointer to Inbound or Outbound SA base. 605 */ 606 __rte_experimental 607 union rte_pmd_cnxk_ipsec_hw_sa *rte_pmd_cnxk_hw_session_base_get(uint16_t portid, bool inb); 608 609 /** 610 * Executes a CPT flush on the specified session. 611 * 612 * @param portid 613 * Port identifier of Ethernet device. 614 * @param sess 615 * Handle of the session on which the CPT flush will be executed. 616 * @param inb 617 * Determines the type of SA to be flushed, Inbound or Outbound. 618 * 619 * @return 620 * 0 Upon success, a negative errno value otherwise. 621 */ 622 __rte_experimental 623 int rte_pmd_cnxk_sa_flush(uint16_t portid, union rte_pmd_cnxk_ipsec_hw_sa *sess, bool inb); 624 625 /** 626 * Get queue pointer of Inline Device. 627 * 628 * @return 629 * - Pointer to queue structure that would be the input to submit API. 630 * - NULL upon failure. 631 */ 632 __rte_experimental 633 struct rte_pmd_cnxk_inl_dev_q *rte_pmd_cnxk_inl_dev_qptr_get(void); 634 635 /** 636 * Submit CPT instruction(s) (cpt_inst_s) to Inline Device. 637 * 638 * @param qptr 639 * Pointer obtained with ``rte_pmd_cnxk_inl_dev_qptr_get``. 640 * @param inst 641 * Pointer to an array of ``cpt_inst_s`` prapared by application. 642 * @param nb_inst 643 * Number of instructions to be processed. 644 * 645 * @return 646 * Number of instructions processed. 647 */ 648 __rte_experimental 649 uint16_t rte_pmd_cnxk_inl_dev_submit(struct rte_pmd_cnxk_inl_dev_q *qptr, void *inst, 650 uint16_t nb_inst); 651 652 /** 653 * Retrieves the hardware statistics of a given port and stats type. 654 * 655 * @param portid 656 * Port identifier of Ethernet device. 657 * @param type 658 * The type of hardware statistics to retrieve, as defined in the 659 * ``enum rte_pmd_cnxk_cpt_q_stats_type``. 660 * @param stats 661 * Pointer where the retrieved statistics will be stored. 662 * @param idx 663 * The index of the queue of a given type. 664 * 665 * @return 666 * 0 Upon success, a negative errno value otherwise. 667 */ 668 __rte_experimental 669 int rte_pmd_cnxk_cpt_q_stats_get(uint16_t portid, enum rte_pmd_cnxk_cpt_q_stats_type type, 670 struct rte_pmd_cnxk_cpt_q_stats *stats, uint16_t idx); 671 672 /** 673 * Set the configuration for hardware inline inbound IPsec processing. This API must be 674 * called before calling the ``rte_eth_dev_configure`` API. 675 * 676 * @param portid 677 * Port identifier of Ethernet device. 678 * @param cfg 679 * Pointer to the IPsec inbound configuration structure. 680 */ 681 __rte_experimental 682 void rte_pmd_cnxk_hw_inline_inb_cfg_set(uint16_t portid, struct rte_pmd_cnxk_ipsec_inb_cfg *cfg); 683 684 /** 685 * Retrieves model name on which it is running as a string. 686 * 687 * @return 688 * Returns model string, ex."cn10ka_a1" 689 */ 690 __rte_experimental 691 const char *rte_pmd_cnxk_model_str_get(void); 692 #endif /* _PMD_CNXK_H_ */ 693