1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. 4 * Copyright 2016 NXP 5 * 6 */ 7 8 #ifndef _RTE_DPAA2_SEC_PMD_PRIVATE_H_ 9 #define _RTE_DPAA2_SEC_PMD_PRIVATE_H_ 10 11 #include <rte_security_driver.h> 12 13 #define CRYPTODEV_NAME_DPAA2_SEC_PMD crypto_dpaa2_sec 14 /**< NXP DPAA2 - SEC PMD device name */ 15 16 #define MAX_QUEUES 64 17 #define MAX_DESC_SIZE 64 18 /** private data structure for each DPAA2_SEC device */ 19 struct dpaa2_sec_dev_private { 20 void *mc_portal; /**< MC Portal for configuring this device */ 21 void *hw; /**< Hardware handle for this device.Used by NADK framework */ 22 struct rte_mempool *fle_pool; /* per device memory pool for FLE */ 23 int32_t hw_id; /**< An unique ID of this device instance */ 24 int32_t vfio_fd; /**< File descriptor received via VFIO */ 25 uint16_t token; /**< Token required by DPxxx objects */ 26 unsigned int max_nb_queue_pairs; 27 /**< Max number of queue pairs supported by device */ 28 }; 29 30 struct dpaa2_sec_qp { 31 struct dpaa2_queue rx_vq; 32 struct dpaa2_queue tx_vq; 33 }; 34 35 enum shr_desc_type { 36 DESC_UPDATE, 37 DESC_FINAL, 38 DESC_INITFINAL, 39 }; 40 41 #define DIR_ENC 1 42 #define DIR_DEC 0 43 44 #define DPAA2_IPv6_DEFAULT_VTC_FLOW 0x60000000 45 46 #define DPAA2_SET_FLC_EWS(flc) (flc->word1_bits23_16 |= 0x1) 47 #define DPAA2_SET_FLC_RSC(flc) (flc->word1_bits31_24 |= 0x1) 48 #define DPAA2_SET_FLC_REUSE_BS(flc) (flc->mode_bits |= 0x8000) 49 #define DPAA2_SET_FLC_REUSE_FF(flc) (flc->mode_bits |= 0x2000) 50 51 /* SEC Flow Context Descriptor */ 52 struct sec_flow_context { 53 /* word 0 */ 54 uint16_t word0_sdid; /* 11-0 SDID */ 55 uint16_t word0_res; /* 31-12 reserved */ 56 57 /* word 1 */ 58 uint8_t word1_sdl; /* 5-0 SDL */ 59 /* 7-6 reserved */ 60 61 uint8_t word1_bits_15_8; /* 11-8 CRID */ 62 /* 14-12 reserved */ 63 /* 15 CRJD */ 64 65 uint8_t word1_bits23_16; /* 16 EWS */ 66 /* 17 DAC */ 67 /* 18,19,20 ? */ 68 /* 23-21 reserved */ 69 70 uint8_t word1_bits31_24; /* 24 RSC */ 71 /* 25 RBMT */ 72 /* 31-26 reserved */ 73 74 /* word 2 RFLC[31-0] */ 75 uint32_t word2_rflc_31_0; 76 77 /* word 3 RFLC[63-32] */ 78 uint32_t word3_rflc_63_32; 79 80 /* word 4 */ 81 uint16_t word4_iicid; /* 15-0 IICID */ 82 uint16_t word4_oicid; /* 31-16 OICID */ 83 84 /* word 5 */ 85 uint32_t word5_ofqid:24; /* 23-0 OFQID */ 86 uint32_t word5_31_24:8; 87 /* 24 OSC */ 88 /* 25 OBMT */ 89 /* 29-26 reserved */ 90 /* 31-30 ICR */ 91 92 /* word 6 */ 93 uint32_t word6_oflc_31_0; 94 95 /* word 7 */ 96 uint32_t word7_oflc_63_32; 97 98 /* Word 8-15 storage profiles */ 99 uint16_t dl; /**< DataLength(correction) */ 100 uint16_t reserved; /**< reserved */ 101 uint16_t dhr; /**< DataHeadRoom(correction) */ 102 uint16_t mode_bits; /**< mode bits */ 103 uint16_t bpv0; /**< buffer pool0 valid */ 104 uint16_t bpid0; /**< Bypass Memory Translation */ 105 uint16_t bpv1; /**< buffer pool1 valid */ 106 uint16_t bpid1; /**< Bypass Memory Translation */ 107 uint64_t word_12_15[2]; /**< word 12-15 are reserved */ 108 }; 109 110 struct sec_flc_desc { 111 struct sec_flow_context flc; 112 uint32_t desc[MAX_DESC_SIZE]; 113 }; 114 115 struct ctxt_priv { 116 struct rte_mempool *fle_pool; /* per device memory pool for FLE */ 117 struct sec_flc_desc flc_desc[0]; 118 }; 119 120 enum dpaa2_sec_op_type { 121 DPAA2_SEC_NONE, /*!< No Cipher operations*/ 122 DPAA2_SEC_CIPHER,/*!< CIPHER operations */ 123 DPAA2_SEC_AUTH, /*!< Authentication Operations */ 124 DPAA2_SEC_AEAD, /*!< AEAD (AES-GCM/CCM) type operations */ 125 DPAA2_SEC_CIPHER_HASH, /*!< Authenticated Encryption with 126 * associated data 127 */ 128 DPAA2_SEC_HASH_CIPHER, /*!< Encryption with Authenticated 129 * associated data 130 */ 131 DPAA2_SEC_IPSEC, /*!< IPSEC protocol operations*/ 132 DPAA2_SEC_PDCP, /*!< PDCP protocol operations*/ 133 DPAA2_SEC_PKC, /*!< Public Key Cryptographic Operations */ 134 DPAA2_SEC_MAX 135 }; 136 137 struct dpaa2_sec_aead_ctxt { 138 uint16_t auth_only_len; /*!< Length of data for Auth only */ 139 uint8_t auth_cipher_text; /**< Authenticate/cipher ordering */ 140 }; 141 142 /* 143 * The structure is to be filled by user for PDCP Protocol 144 */ 145 struct dpaa2_pdcp_ctxt { 146 enum rte_security_pdcp_domain domain; /*!< Data/Control mode*/ 147 int8_t bearer; /*!< PDCP bearer ID */ 148 int8_t pkt_dir;/*!< PDCP Frame Direction 0:UL 1:DL*/ 149 int8_t hfn_ovd;/*!< Overwrite HFN per packet*/ 150 uint8_t sn_size; /*!< Sequence number size, 5/7/12/15/18 */ 151 uint32_t hfn_ovd_offset;/*!< offset from rte_crypto_op at which 152 * per packet hfn is stored 153 */ 154 uint32_t hfn; /*!< Hyper Frame Number */ 155 uint32_t hfn_threshold; /*!< HFN Threashold for key renegotiation */ 156 }; 157 158 typedef struct dpaa2_sec_session_entry { 159 void *ctxt; 160 uint8_t ctxt_type; 161 uint8_t dir; /*!< Operation Direction */ 162 enum rte_crypto_cipher_algorithm cipher_alg; /*!< Cipher Algorithm*/ 163 enum rte_crypto_auth_algorithm auth_alg; /*!< Authentication Algorithm*/ 164 enum rte_crypto_aead_algorithm aead_alg; /*!< AEAD Algorithm*/ 165 union { 166 struct { 167 uint8_t *data; /**< pointer to key data */ 168 size_t length; /**< key length in bytes */ 169 } aead_key; 170 struct { 171 struct { 172 uint8_t *data; /**< pointer to key data */ 173 size_t length; /**< key length in bytes */ 174 } cipher_key; 175 struct { 176 uint8_t *data; /**< pointer to key data */ 177 size_t length; /**< key length in bytes */ 178 } auth_key; 179 }; 180 }; 181 union { 182 struct { 183 struct { 184 uint16_t length; /**< IV length in bytes */ 185 uint16_t offset; /**< IV offset in bytes */ 186 } iv; 187 uint16_t digest_length; 188 uint8_t status; 189 union { 190 struct dpaa2_sec_aead_ctxt aead_ctxt; 191 } ext_params; 192 }; 193 struct dpaa2_pdcp_ctxt pdcp; 194 }; 195 } dpaa2_sec_session; 196 197 static const struct rte_cryptodev_capabilities dpaa2_sec_capabilities[] = { 198 { /* MD5 HMAC */ 199 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 200 {.sym = { 201 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 202 {.auth = { 203 .algo = RTE_CRYPTO_AUTH_MD5_HMAC, 204 .block_size = 64, 205 .key_size = { 206 .min = 1, 207 .max = 64, 208 .increment = 1 209 }, 210 .digest_size = { 211 .min = 1, 212 .max = 16, 213 .increment = 1 214 }, 215 .iv_size = { 0 } 216 }, } 217 }, } 218 }, 219 { /* SHA1 HMAC */ 220 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 221 {.sym = { 222 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 223 {.auth = { 224 .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, 225 .block_size = 64, 226 .key_size = { 227 .min = 1, 228 .max = 64, 229 .increment = 1 230 }, 231 .digest_size = { 232 .min = 1, 233 .max = 20, 234 .increment = 1 235 }, 236 .iv_size = { 0 } 237 }, } 238 }, } 239 }, 240 { /* SHA224 HMAC */ 241 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 242 {.sym = { 243 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 244 {.auth = { 245 .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, 246 .block_size = 64, 247 .key_size = { 248 .min = 1, 249 .max = 64, 250 .increment = 1 251 }, 252 .digest_size = { 253 .min = 1, 254 .max = 28, 255 .increment = 1 256 }, 257 .iv_size = { 0 } 258 }, } 259 }, } 260 }, 261 { /* SHA256 HMAC */ 262 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 263 {.sym = { 264 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 265 {.auth = { 266 .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, 267 .block_size = 64, 268 .key_size = { 269 .min = 1, 270 .max = 64, 271 .increment = 1 272 }, 273 .digest_size = { 274 .min = 1, 275 .max = 32, 276 .increment = 1 277 }, 278 .iv_size = { 0 } 279 }, } 280 }, } 281 }, 282 { /* SHA384 HMAC */ 283 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 284 {.sym = { 285 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 286 {.auth = { 287 .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, 288 .block_size = 128, 289 .key_size = { 290 .min = 1, 291 .max = 128, 292 .increment = 1 293 }, 294 .digest_size = { 295 .min = 1, 296 .max = 48, 297 .increment = 1 298 }, 299 .iv_size = { 0 } 300 }, } 301 }, } 302 }, 303 { /* SHA512 HMAC */ 304 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 305 {.sym = { 306 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 307 {.auth = { 308 .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, 309 .block_size = 128, 310 .key_size = { 311 .min = 1, 312 .max = 128, 313 .increment = 1 314 }, 315 .digest_size = { 316 .min = 1, 317 .max = 64, 318 .increment = 1 319 }, 320 .iv_size = { 0 } 321 }, } 322 }, } 323 }, 324 { /* AES GCM */ 325 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 326 {.sym = { 327 .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD, 328 {.aead = { 329 .algo = RTE_CRYPTO_AEAD_AES_GCM, 330 .block_size = 16, 331 .key_size = { 332 .min = 16, 333 .max = 32, 334 .increment = 8 335 }, 336 .digest_size = { 337 .min = 8, 338 .max = 16, 339 .increment = 4 340 }, 341 .aad_size = { 342 .min = 0, 343 .max = 240, 344 .increment = 1 345 }, 346 .iv_size = { 347 .min = 12, 348 .max = 12, 349 .increment = 0 350 }, 351 }, } 352 }, } 353 }, 354 { /* AES CBC */ 355 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 356 {.sym = { 357 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 358 {.cipher = { 359 .algo = RTE_CRYPTO_CIPHER_AES_CBC, 360 .block_size = 16, 361 .key_size = { 362 .min = 16, 363 .max = 32, 364 .increment = 8 365 }, 366 .iv_size = { 367 .min = 16, 368 .max = 16, 369 .increment = 0 370 } 371 }, } 372 }, } 373 }, 374 { /* AES CTR */ 375 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 376 {.sym = { 377 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 378 {.cipher = { 379 .algo = RTE_CRYPTO_CIPHER_AES_CTR, 380 .block_size = 16, 381 .key_size = { 382 .min = 16, 383 .max = 32, 384 .increment = 8 385 }, 386 .iv_size = { 387 .min = 16, 388 .max = 16, 389 .increment = 0 390 }, 391 }, } 392 }, } 393 }, 394 { /* 3DES CBC */ 395 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 396 {.sym = { 397 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 398 {.cipher = { 399 .algo = RTE_CRYPTO_CIPHER_3DES_CBC, 400 .block_size = 8, 401 .key_size = { 402 .min = 16, 403 .max = 24, 404 .increment = 8 405 }, 406 .iv_size = { 407 .min = 8, 408 .max = 8, 409 .increment = 0 410 } 411 }, } 412 }, } 413 }, 414 { /* SNOW 3G (UIA2) */ 415 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 416 {.sym = { 417 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 418 {.auth = { 419 .algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2, 420 .block_size = 16, 421 .key_size = { 422 .min = 16, 423 .max = 16, 424 .increment = 0 425 }, 426 .digest_size = { 427 .min = 4, 428 .max = 4, 429 .increment = 0 430 }, 431 .iv_size = { 432 .min = 16, 433 .max = 16, 434 .increment = 0 435 } 436 }, } 437 }, } 438 }, 439 { /* SNOW 3G (UEA2) */ 440 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 441 {.sym = { 442 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 443 {.cipher = { 444 .algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2, 445 .block_size = 16, 446 .key_size = { 447 .min = 16, 448 .max = 16, 449 .increment = 0 450 }, 451 .iv_size = { 452 .min = 16, 453 .max = 16, 454 .increment = 0 455 } 456 }, } 457 }, } 458 }, 459 { /* ZUC (EEA3) */ 460 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 461 {.sym = { 462 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 463 {.cipher = { 464 .algo = RTE_CRYPTO_CIPHER_ZUC_EEA3, 465 .block_size = 16, 466 .key_size = { 467 .min = 16, 468 .max = 16, 469 .increment = 0 470 }, 471 .iv_size = { 472 .min = 16, 473 .max = 16, 474 .increment = 0 475 } 476 }, } 477 }, } 478 }, 479 { /* ZUC (EIA3) */ 480 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 481 {.sym = { 482 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 483 {.auth = { 484 .algo = RTE_CRYPTO_AUTH_ZUC_EIA3, 485 .block_size = 16, 486 .key_size = { 487 .min = 16, 488 .max = 16, 489 .increment = 0 490 }, 491 .digest_size = { 492 .min = 4, 493 .max = 4, 494 .increment = 0 495 }, 496 .iv_size = { 497 .min = 16, 498 .max = 16, 499 .increment = 0 500 } 501 }, } 502 }, } 503 }, 504 RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() 505 }; 506 507 static const struct rte_cryptodev_capabilities dpaa2_pdcp_capabilities[] = { 508 { /* SNOW 3G (UIA2) */ 509 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 510 {.sym = { 511 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 512 {.auth = { 513 .algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2, 514 .block_size = 16, 515 .key_size = { 516 .min = 16, 517 .max = 16, 518 .increment = 0 519 }, 520 .digest_size = { 521 .min = 4, 522 .max = 4, 523 .increment = 0 524 }, 525 .iv_size = { 526 .min = 16, 527 .max = 16, 528 .increment = 0 529 } 530 }, } 531 }, } 532 }, 533 { /* SNOW 3G (UEA2) */ 534 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 535 {.sym = { 536 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 537 {.cipher = { 538 .algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2, 539 .block_size = 16, 540 .key_size = { 541 .min = 16, 542 .max = 16, 543 .increment = 0 544 }, 545 .iv_size = { 546 .min = 16, 547 .max = 16, 548 .increment = 0 549 } 550 }, } 551 }, } 552 }, 553 { /* AES CTR */ 554 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 555 {.sym = { 556 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 557 {.cipher = { 558 .algo = RTE_CRYPTO_CIPHER_AES_CTR, 559 .block_size = 16, 560 .key_size = { 561 .min = 16, 562 .max = 32, 563 .increment = 8 564 }, 565 .iv_size = { 566 .min = 16, 567 .max = 16, 568 .increment = 0 569 } 570 }, } 571 }, } 572 }, 573 { /* NULL (AUTH) */ 574 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 575 {.sym = { 576 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 577 {.auth = { 578 .algo = RTE_CRYPTO_AUTH_NULL, 579 .block_size = 1, 580 .key_size = { 581 .min = 0, 582 .max = 0, 583 .increment = 0 584 }, 585 .digest_size = { 586 .min = 0, 587 .max = 0, 588 .increment = 0 589 }, 590 .iv_size = { 0 } 591 }, }, 592 }, }, 593 }, 594 { /* NULL (CIPHER) */ 595 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 596 {.sym = { 597 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 598 {.cipher = { 599 .algo = RTE_CRYPTO_CIPHER_NULL, 600 .block_size = 1, 601 .key_size = { 602 .min = 0, 603 .max = 0, 604 .increment = 0 605 }, 606 .iv_size = { 607 .min = 0, 608 .max = 0, 609 .increment = 0 610 } 611 }, }, 612 }, } 613 }, 614 { /* ZUC (EEA3) */ 615 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 616 {.sym = { 617 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 618 {.cipher = { 619 .algo = RTE_CRYPTO_CIPHER_ZUC_EEA3, 620 .block_size = 16, 621 .key_size = { 622 .min = 16, 623 .max = 16, 624 .increment = 0 625 }, 626 .iv_size = { 627 .min = 16, 628 .max = 16, 629 .increment = 0 630 } 631 }, } 632 }, } 633 }, 634 { /* ZUC (EIA3) */ 635 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 636 {.sym = { 637 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 638 {.auth = { 639 .algo = RTE_CRYPTO_AUTH_ZUC_EIA3, 640 .block_size = 16, 641 .key_size = { 642 .min = 16, 643 .max = 16, 644 .increment = 0 645 }, 646 .digest_size = { 647 .min = 4, 648 .max = 4, 649 .increment = 0 650 }, 651 .iv_size = { 652 .min = 16, 653 .max = 16, 654 .increment = 0 655 } 656 }, } 657 }, } 658 }, 659 660 RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() 661 }; 662 663 static const struct rte_security_capability dpaa2_sec_security_cap[] = { 664 { /* IPsec Lookaside Protocol offload ESP Transport Egress */ 665 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, 666 .protocol = RTE_SECURITY_PROTOCOL_IPSEC, 667 .ipsec = { 668 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, 669 .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL, 670 .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS, 671 .options = { 0 } 672 }, 673 .crypto_capabilities = dpaa2_sec_capabilities 674 }, 675 { /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */ 676 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, 677 .protocol = RTE_SECURITY_PROTOCOL_IPSEC, 678 .ipsec = { 679 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, 680 .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL, 681 .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS, 682 .options = { 0 } 683 }, 684 .crypto_capabilities = dpaa2_sec_capabilities 685 }, 686 { /* PDCP Lookaside Protocol offload Data */ 687 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, 688 .protocol = RTE_SECURITY_PROTOCOL_PDCP, 689 .pdcp = { 690 .domain = RTE_SECURITY_PDCP_MODE_DATA, 691 .capa_flags = 0 692 }, 693 .crypto_capabilities = dpaa2_pdcp_capabilities 694 }, 695 { /* PDCP Lookaside Protocol offload Control */ 696 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, 697 .protocol = RTE_SECURITY_PROTOCOL_PDCP, 698 .pdcp = { 699 .domain = RTE_SECURITY_PDCP_MODE_CONTROL, 700 .capa_flags = 0 701 }, 702 .crypto_capabilities = dpaa2_pdcp_capabilities 703 }, 704 { 705 .action = RTE_SECURITY_ACTION_TYPE_NONE 706 } 707 }; 708 709 /** 710 * Checksum 711 * 712 * @param buffer calculate chksum for buffer 713 * @param len buffer length 714 * 715 * @return checksum value in host cpu order 716 */ 717 static inline uint16_t 718 calc_chksum(void *buffer, int len) 719 { 720 uint16_t *buf = (uint16_t *)buffer; 721 uint32_t sum = 0; 722 uint16_t result; 723 724 for (sum = 0; len > 1; len -= 2) 725 sum += *buf++; 726 727 if (len == 1) 728 sum += *(unsigned char *)buf; 729 730 sum = (sum >> 16) + (sum & 0xFFFF); 731 sum += (sum >> 16); 732 result = ~sum; 733 734 return result; 735 } 736 737 #endif /* _RTE_DPAA2_SEC_PMD_PRIVATE_H_ */ 738