From 266b0663c598b7e50c2998974c16f89b7ac23e3a Mon Sep 17 00:00:00 2001 From: Krzysztof Zdziarski Date: Mon, 12 Jun 2023 13:10:03 -0400 Subject: [PATCH] =?UTF-8?q?qat:=20Add=20Intel=C2=AE=204xxx=20Series=20VF?= =?UTF-8?q?=20driver=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overview: Intel(R) QuickAssist Technology (Intel(R) QAT) provides hardware acceleration for offloading security, authentication and compression services from the CPU, thus significantly increasing the performance and efficiency of standard platform solutions. This commit introduces: - IntelĀ® 4xxx Series VF driver support. - Device configurability via sysctls. - UIO support for IntelĀ® 4xxx Series devices. Patch co-authored by: Krzysztof Zdziarski Patch co-authored by: Michal Gulbicki Patch co-authored by: Julian Grajkowski Patch co-authored by: Piotr Kasierski Patch co-authored by: Lukasz Kolodzinski Patch co-authored by: Karol Grzadziel Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D39850 --- share/man/man4/qat.4 | 57 +- sys/contrib/dev/qat/qat_4xxx.bin | Bin 532308 -> 665356 bytes sys/dev/qat/include/adf_cfg_device.h | 24 +- sys/dev/qat/include/adf_gen2_pfvf.h | 27 + sys/dev/qat/include/adf_gen4_pfvf.h | 16 + sys/dev/qat/include/adf_gen4_timer.h | 17 + sys/dev/qat/include/adf_gen4vf_hw_csr_data.h | 151 + sys/dev/qat/include/adf_pf2vf_msg.h | 182 - sys/dev/qat/include/adf_pfvf_vf_msg.h | 13 + .../qat/include/common/adf_accel_devices.h | 94 +- sys/dev/qat/include/common/adf_cfg.h | 5 + sys/dev/qat/include/common/adf_cfg_common.h | 21 +- sys/dev/qat/include/common/adf_cfg_strings.h | 6 + sys/dev/qat/include/common/adf_cfg_sysctl.h | 12 + sys/dev/qat/include/common/adf_common_drv.h | 75 +- sys/dev/qat/include/common/adf_gen2_hw_data.h | 24 + sys/dev/qat/include/common/adf_gen4_hw_data.h | 41 + sys/dev/qat/include/common/adf_pfvf_msg.h | 260 + sys/dev/qat/include/common/adf_pfvf_utils.h | 44 + .../qat/include/common/adf_pfvf_vf_proto.h | 32 + sys/dev/qat/include/common/adf_uio.h | 17 + sys/dev/qat/include/common/adf_uio_cleanup.h | 11 + sys/dev/qat/include/common/adf_uio_control.h | 43 + sys/dev/qat/qat/qat_ocf.c | 202 +- .../qat_api/common/compression/dc_buffers.c | 16 + .../qat/qat_api/common/compression/dc_chain.c | 102 + .../qat_api/common/compression/dc_datapath.c | 6 + .../qat/qat_api/common/compression/dc_dp.c | 8 + .../common/compression/dc_ns_datapath.c | 72 + .../common/compression/dc_ns_header_footer.c | 46 + .../qat_api/common/compression/dc_session.c | 27 +- .../common/compression/include/dc_session.h | 2 - .../common/crypto/sym/key/lac_sym_key.c | 8 - .../common/crypto/sym/lac_sym_alg_chain.c | 4 +- .../qat/qat_api/common/ctrl/sal_compression.c | 63 +- .../qat_api/common/ctrl/sal_ctrl_services.c | 101 +- .../qat_api/common/ctrl/sal_get_instances.c | 288 + .../common/include/sal_types_compression.h | 5 +- sys/dev/qat/qat_api/common/stubs/lac_stubs.c | 191 + .../qat_api/firmware/include/icp_qat_fw_mmp.h | 11650 +++++++++------- .../firmware/include/icp_qat_fw_mmp_ids.h | 508 +- sys/dev/qat/qat_api/include/cpa.h | 128 +- sys/dev/qat/qat_api/include/cpa_dev.h | 2 +- sys/dev/qat/qat_api/include/cpa_types.h | 21 +- sys/dev/qat/qat_api/include/dc/cpa_dc.h | 1010 +- sys/dev/qat/qat_api/include/dc/cpa_dc_bp.h | 2 +- sys/dev/qat/qat_api/include/dc/cpa_dc_chain.h | 659 + sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h | 97 +- .../qat/qat_api/include/icp_sal_versions.h | 2 +- .../qat/qat_api/include/lac/cpa_cy_common.h | 39 +- sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h | 8 +- sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h | 2 +- sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h | 508 +- sys/dev/qat/qat_api/include/lac/cpa_cy_ecdh.h | 3 +- .../qat/qat_api/include/lac/cpa_cy_ecdsa.h | 19 +- .../qat/qat_api/include/lac/cpa_cy_ecsm2.h | 1464 ++ sys/dev/qat/qat_api/include/lac/cpa_cy_im.h | 5 +- sys/dev/qat/qat_api/include/lac/cpa_cy_key.h | 9 +- sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h | 853 ++ sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h | 20 +- .../qat/qat_api/include/lac/cpa_cy_prime.h | 2 +- sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h | 18 +- sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h | 17 +- .../qat/qat_api/include/lac/cpa_cy_sym_dp.h | 2 +- .../qat_direct/include/icp_accel_devices.h | 5 +- sys/dev/qat/qat_common/adf_aer.c | 2 - sys/dev/qat/qat_common/adf_cfg.c | 49 + sys/dev/qat/qat_common/adf_cfg_device.c | 570 +- sys/dev/qat/qat_common/adf_cfg_sysctl.c | 343 + sys/dev/qat/qat_common/adf_ctl_drv.c | 491 + .../qat_common/adf_freebsd_dev_processes.c | 677 + sys/dev/qat/qat_common/adf_freebsd_uio.c | 450 + .../qat/qat_common/adf_freebsd_uio_cleanup.c | 404 + sys/dev/qat/qat_common/adf_gen2_hw_data.c | 18 +- sys/dev/qat/qat_common/adf_gen4_hw_data.c | 85 +- sys/dev/qat/qat_common/adf_gen4_pfvf.c | 131 + sys/dev/qat/qat_common/adf_gen4_timer.c | 134 + .../qat/qat_common/adf_gen4vf_hw_csr_data.c | 162 + sys/dev/qat/qat_common/adf_hw_arbiter.c | 26 +- sys/dev/qat/qat_common/adf_init.c | 46 +- .../qat/qat_common/adf_pf2vf_capabilities.c | 147 - sys/dev/qat/qat_common/adf_pf2vf_msg.c | 896 -- .../qat_common/adf_pf2vf_ring_to_svc_map.c | 74 - sys/dev/qat/qat_common/adf_pfvf_utils.c | 102 + sys/dev/qat/qat_common/adf_pfvf_vf_msg.c | 185 + sys/dev/qat/qat_common/adf_pfvf_vf_proto.c | 405 + sys/dev/qat/qat_common/adf_transport.c | 14 +- sys/dev/qat/qat_common/adf_vf2pf_msg.c | 275 - sys/dev/qat/qat_common/adf_vf_isr.c | 346 +- sys/dev/qat/qat_common/qat_common_module.c | 5 +- .../qat/qat_hw/qat_200xx/adf_200xx_hw_data.c | 21 +- .../qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c | 93 +- .../qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h | 6 +- sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c | 10 +- .../qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c | 390 + .../qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h | 34 + sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c | 282 + .../qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c | 21 +- .../qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c | 21 +- .../qat/qat_hw/qat_c62x/adf_c62x_hw_data.c | 21 +- .../qat_dh895xcc/adf_dh895xcc_hw_data.c | 21 +- sys/modules/qat/qat_api/Makefile | 4 + sys/modules/qat/qat_common/Makefile | 14 +- sys/modules/qat/qat_hw/Makefile | 1 + 104 files changed, 18578 insertions(+), 7764 deletions(-) create mode 100644 sys/dev/qat/include/adf_gen2_pfvf.h create mode 100644 sys/dev/qat/include/adf_gen4_pfvf.h create mode 100644 sys/dev/qat/include/adf_gen4_timer.h create mode 100644 sys/dev/qat/include/adf_gen4vf_hw_csr_data.h delete mode 100644 sys/dev/qat/include/adf_pf2vf_msg.h create mode 100644 sys/dev/qat/include/adf_pfvf_vf_msg.h create mode 100644 sys/dev/qat/include/common/adf_cfg_sysctl.h create mode 100644 sys/dev/qat/include/common/adf_pfvf_msg.h create mode 100644 sys/dev/qat/include/common/adf_pfvf_utils.h create mode 100644 sys/dev/qat/include/common/adf_pfvf_vf_proto.h create mode 100644 sys/dev/qat/include/common/adf_uio.h create mode 100644 sys/dev/qat/include/common/adf_uio_cleanup.h create mode 100644 sys/dev/qat/include/common/adf_uio_control.h create mode 100644 sys/dev/qat/qat_api/common/compression/dc_chain.c create mode 100644 sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c create mode 100644 sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c create mode 100644 sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c create mode 100644 sys/dev/qat/qat_api/include/dc/cpa_dc_chain.h create mode 100644 sys/dev/qat/qat_api/include/lac/cpa_cy_ecsm2.h create mode 100644 sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h create mode 100644 sys/dev/qat/qat_common/adf_cfg_sysctl.c create mode 100644 sys/dev/qat/qat_common/adf_ctl_drv.c create mode 100644 sys/dev/qat/qat_common/adf_freebsd_dev_processes.c create mode 100644 sys/dev/qat/qat_common/adf_freebsd_uio.c create mode 100644 sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c create mode 100644 sys/dev/qat/qat_common/adf_gen4_pfvf.c create mode 100644 sys/dev/qat/qat_common/adf_gen4_timer.c create mode 100644 sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c delete mode 100644 sys/dev/qat/qat_common/adf_pf2vf_capabilities.c delete mode 100644 sys/dev/qat/qat_common/adf_pf2vf_msg.c delete mode 100644 sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c create mode 100644 sys/dev/qat/qat_common/adf_pfvf_utils.c create mode 100644 sys/dev/qat/qat_common/adf_pfvf_vf_msg.c create mode 100644 sys/dev/qat/qat_common/adf_pfvf_vf_proto.c delete mode 100644 sys/dev/qat/qat_common/adf_vf2pf_msg.c create mode 100644 sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c create mode 100644 sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h create mode 100644 sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c diff --git a/share/man/man4/qat.4 b/share/man/man4/qat.4 index e8a46a99e949..77b85d729ffa 100644 --- a/share/man/man4/qat.4 +++ b/share/man/man4/qat.4 @@ -1,7 +1,7 @@ .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright(c) 2007-2022 Intel Corporation .\" $FreeBSD$ -.Dd September 1, 2022 +.Dd May 4, 2023 .Dt QAT 4 .Os .Sh NAME @@ -101,6 +101,61 @@ For details of usage and supported operations and algorithms refer to the documentation mentioned above and .Sx SEE ALSO section. +.Sh SYSCTL_VARIABLES +Following variables may be used to reconfigure the QAT device.\& +For configuration persistence those variables may be set before loading the driver, either via +.Xr kenv 1 +or +.Xr loader.conf(5). +The device specific configuration options are prefixed with +.Va dev.qat.X\&. +where X is the device number. +The specific device needs to be in "down" state before changing the configuration. +.Bl -tag -width indent +.It Va state +Show current state of the device. Override the device state. Possible values: "down", "up". + +NOTE: If the symmetric services are used for device the qat_ocf driver needs to be disabled prior the device +reconfiguration. +Following variable may be used to enable/disable the QAT cryptographic framework connectivity +.Va dev.qat_ocf.0.enable\&. +Enabled by default. +.It Va cfg_services +Override the device services enabled: symmetric, asymmetric, data compression. +Possible values: "sym", "asym", "dc", "sym;dc", "asym;dc", "sym;asym". +Default services configured are "sym;asym" for even and "dc" for odd devices. +.It Va cfg_mode +Override the device mode configuration for kernel space and user space instances. +Possible values: "ks", "us", "ks;us". +Default value "ks;us". +.It Va num_user_processes +Override the number of uio user space processes that can connect to the QAT device. +Default: 2 +.El +.Pp +The following +.Xr sysctl 8 +variables are read-only: +.Bl -tag -width indent +.It Va frequency +QAT device frequency value. +.It Va mmp_version +QAT MMP Library revision number. +.It Va hw_version +QAT hardware revision number. +.It Va fw_version +QAT firmware revision number. +.It Va dev_cfg +Summary of device specific configuration. +.It Va heartbeat +QAT device heartbeat status. Value '1' indicates that the device is operational. +'0' value means that the device is not responsive. Device requires restart. +.It Va heartbeat_failed +Number of QAT heartbeat failures received. +.It Va heartbeat_sent +Number of QAT heartbeat requests sent. +.El + .Sh COMPATIBILITY The .Nm diff --git a/sys/contrib/dev/qat/qat_4xxx.bin b/sys/contrib/dev/qat/qat_4xxx.bin index baec3ad9ca32a87113fe185afc94ec264ff5fa4f..66dd803fe419c681f7fa19381e716179bd226fb0 100644 GIT binary patch literal 665356 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
^{`^nNk%XDAmE&e3uz2Sdb*@DHCy71cfP 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 z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR z1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR1BwHR L1BwH`91i?{yaB22 literal 532308 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 z%0DQt=`-RVnPRt(A4m8{z`lv_k1}zADg4ns@r=Shio`<*ofqIUR`FkjUnPZqxcH@o zf8?t44*w`?e_%xKn5CTef}P6m^b7y^#o#fpE8-v3@9uNLcci~P4tj0GkKiA_7;LBf zDD5>1{{Y{cg@2%ragGK)85jOh9$bc=A^K_=eO=(dv&ui#;YS94BKR2okre&`9vQwc zM)=3WRsDQ4{xJr9eAx++_bSwPB7DJ5*dux@^fE#2Ek$lm(D$CRMEZOv_EjO^C6=9_ z?LfmHqVLI==RP2GUh})LTUtm!B7RZu0ll4m_@C%2=Go$UzZ|s0PIdJ8;TBK*N{>hE zCFER7;QdPW=e%SNd}Udbbwc*5RMHQ>yWJW1l_HLXMY?6O)jAj2$_Jf>cTE~yW;`v?tD(ZKl4|mA#1*Lv1>rh5dPC0?} zn;x4k?98B_#!IDZZvn_-C6AAcC!0K}khi1hL+V!eG@oO(+GA6%-qv}XQ*mim#!Wv0 z_vk((?m;AuCyu?K(hvB2x6<*UcG~X>{X-AN8`t;wl#iDjz5g5iUY6f;;9vB6b-ww; z5cBYz7GE;@CI)Tyw$hYDc@(^RA^r* zE7LM$)vLLpn7FK0v`)!5c}f&`5UtbeZ|R$G;PU$a&wimX;um6>D)b)VRn;$a|5-!$ z$-qBtZyCD5PX5}E=w-&Q^XmOVUlTg3^$Y!4_+l1%(&tZDhbHn;!ROUD=)~h0(TOMY z1sp6Hr^9~;0TusAy2&o=%tD_jRa*THL19l|b3x{a~t zUEo*;9haFW`J*⋼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%0D?@!fy-Pk;QztM)vx z^Y|l=ZoKlEXa4*HzjC&(f6wsK+qV7a7xUk7YijO^FK+$$Z{K}y1n$PafAV{Mcm3f% zUKV-v!G~`6gCEy@Zy@)pkBZ`?>~nYi^R*xQ+iU*guZCXH`@knxeej=F z-@Eyr-!|*R^Pk@MHw|kqGmPusKK}>f#rp0KzOm`4YtFu)`HIiRf4pqyi?=k7zTvfz zt>1j;l5_9+;s07OXa1ZAKKHgQjU96m&wXX<54%rZctPax3u5C>?EkNyykU9akAJZC zF||fLfAm!+Z~5f?U*GZL;v)lJ{?5kU+OwZI>(-0E^8Ax&$ z-~BrKx}l{vz3rh}zV-C^fAF@)kKBFBso(zRAJ!f^d{J`ao{!8;|NF_m{`J59!~3p$ z{;BtF8~dAczxmv{i=Vz@?a{MOuDkZ%UjL7)|6uV|>*6Q2jkJCx{^nDkzWJ)`{6Bp3 z!@qv`i+$g^@1d{#{riqRx2yB2^7{r4{rTW%-#h+t;jb_L?9uHvd@SAY&nNcY{kDem zJ*#%4UiihETN3-uyYVAW|HWt4o%_|-{L!cW`EAd>?(L6!>yn?}bMPHEr4Ie%waI^f z>KmWE`l;f(&b$5NEf;L-`}^-4N-enl3*X3OZnwIeum17{H}m&PU;X;mpjleWQl~`6 z_|rP246Sbb9np`Jy6K&{Yp=WEmYZ(9_Ldv3z4o1H{rvw&|GD(0Td#ZnN6hO!@PQj| zx&G!GZ!q6`tNDia-e#Kp=F;@irRH@XG}9NZNDr(?Uub^l12^6JZu5iheeca5FmJo@ z{U5lAvKK5#FFF6Bi~7wa=9M?S|CSG5_x>A$XDiI}d6+gY{m@M}-*D|4K6K0VH@<&` zd7*jPdvCerrVpC0xqOAW?4o5$uRnj_dh<;myfK%f_7&z8|L+rjZpv%3S+1s1EnEff zv$fuR(|>OH*VSA_d@}y^#h#0Gc(LcPmv}Dyc(M0uUgEjfq8EEV`4Z20TzNmJ=l6SE z6F*s`S4~Ql-Iz)?rLDa#qqrlg%2rYt?lVI_%0jiv_+5YtF|JNh32RDLM9o&#=a0BT zwMKnkDZjos)K^TX4a)lDsjZ-{UK-8$-Gc! z`>c~`+H05h`59|aWoawXVi)YBYL2Uzn}ZAOl(*sbmW;|%-aLD4VRt63y3bx~@6PhV zT-EF_j_nI_s!TiS1JN-A?fd{v5Z3ZF`4-e2gqvoM=D>F~Ut-v;gXml7xQ5mii@ z(1rdb4eNLzuFRydDg~+~fVNUbsZ$FLRnGiB?7a`19anYdd8+$$zbAD|U9yDKSVAhP z+iqdW>W5oc!rfS9Abd2$laxb-Xa|x!v)-&e1Dk!xW*P6mBqd`MAq(Y+2u4_9Qh-Sm z<76vDNqPjslnoBvu|pojCjGx({(OiNNcP2HW;7p^^?uK-fA5c)wr3dZnNRfL z-Fxmi=bm$Z=iFPbUyi-XmP^oe>{aLFBVx(Iq`t>|CX@Fj)Atla8Je6-pl-YD}C z#w%==(C?F;Vj!35J+iY;%J*}9;t>5XjvS&Nr(c{y^uxUQf2JR~>0;x&Z^>P|z8Er(-wU!w;Kwn{F>v3mJccA?bb2K_`cF z-28q@@6N)oJP6%8`-hw7yⅇ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 +#include "adf_accel_devices.h" + +#define ADF_GEN2_ERRSOU3 (0x3A000 + 0x0C) +#define ADF_GEN2_ERRSOU5 (0x3A000 + 0xD8) +#define ADF_GEN2_ERRMSK3 (0x3A000 + 0x1C) +#define ADF_GEN2_ERRMSK5 (0x3A000 + 0xDC) + +static inline void +adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +static inline void +adf_gen2_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +#endif /* ADF_GEN2_PFVF_H */ diff --git a/sys/dev/qat/include/adf_gen4_pfvf.h b/sys/dev/qat/include/adf_gen4_pfvf.h new file mode 100644 index 000000000000..45fa171ae364 --- /dev/null +++ b/sys/dev/qat/include/adf_gen4_pfvf.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4_PFVF_H +#define ADF_GEN4_PFVF_H + +#include "adf_accel_devices.h" + +void adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops); +static inline void +adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +#endif /* ADF_GEN4_PFVF_H */ diff --git a/sys/dev/qat/include/adf_gen4_timer.h b/sys/dev/qat/include/adf_gen4_timer.h new file mode 100644 index 000000000000..e91591772e5e --- /dev/null +++ b/sys/dev/qat/include/adf_gen4_timer.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4_TIMER_H_ +#define ADF_GEN4_TIMER_H_ + +struct adf_accel_dev; + +struct adf_hb_timer_data { + struct adf_accel_dev *accel_dev; + struct work_struct hb_int_timer_work; +}; + +int adf_int_timer_init(struct adf_accel_dev *accel_dev); +void adf_int_timer_exit(struct adf_accel_dev *accel_dev); + +#endif /* ADF_GEN4_TIMER_H_ */ diff --git a/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h b/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h new file mode 100644 index 000000000000..27f10ae729db --- /dev/null +++ b/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4VF_HW_CSR_DATA_H_ +#define ADF_GEN4VF_HW_CSR_DATA_H_ + +#define ADF_RING_CSR_ADDR_OFFSET_GEN4VF 0x0 +#define ADF_RING_BUNDLE_SIZE_GEN4 0x2000 +#define ADF_RING_CSR_RING_HEAD 0x0C0 +#define ADF_RING_CSR_RING_TAIL 0x100 +#define ADF_RING_CSR_E_STAT 0x14C +#define ADF_RING_CSR_RING_CONFIG_GEN4 0x1000 +#define ADF_RING_CSR_RING_LBASE_GEN4 0x1040 +#define ADF_RING_CSR_RING_UBASE_GEN4 0x1080 +#define ADF_RING_CSR_INT_FLAG 0x170 +#define ADF_RING_CSR_INT_FLAG_AND_COL 0x184 +#define ADF_RING_CSR_NEXT_INT_SRCSEL 0x4 +#define ADF_RING_CSR_INT_SRCSEL 0x174 +#define ADF_RING_CSR_INT_COL_EN 0x17C +#define ADF_RING_CSR_INT_COL_CTL 0x180 +#define ADF_RING_CSR_RING_SRV_ARB_EN 0x19C +#define ADF_BANK_INT_SRC_SEL_MASK_GEN4 0x44UL +#define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000 +#define ADF_BANK_INT_FLAG_CLEAR_MASK_GEN4 0x3 +#define ADF_RINGS_PER_INT_SRCSEL_GEN4 2 + +#define BUILD_RING_BASE_ADDR_GEN4(addr, size) \ + ((((addr) >> 6) & (0xFFFFFFFFFFFFFFFFULL << (size))) << 6) +#define READ_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_HEAD + ((ring) << 2)) +#define READ_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_TAIL + ((ring) << 2)) +#define READ_CSR_E_STAT_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_E_STAT) +#define WRITE_CSR_RING_CONFIG_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_CONFIG_GEN4 + ((ring) << 2), \ + (value)) +#define WRITE_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring, value) \ + do { \ + struct resource *_csr_base_addr = csr_base_addr; \ + u32 _bank = bank; \ + u32 _ring = ring; \ + dma_addr_t _value = value; \ + u32 l_base = 0, u_base = 0; \ + l_base = (u32)((_value)&0xFFFFFFFF); \ + u_base = (u32)(((_value)&0xFFFFFFFF00000000ULL) >> 32); \ + ADF_CSR_WR((_csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (_bank)) + \ + ADF_RING_CSR_RING_LBASE_GEN4 + ((_ring) << 2), \ + l_base); \ + ADF_CSR_WR((_csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (_bank)) + \ + ADF_RING_CSR_RING_UBASE_GEN4 + ((_ring) << 2), \ + u_base); \ + } while (0) + +static inline u64 +read_base_gen4vf(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE_GEN4 * bank) + + ADF_RING_CSR_RING_LBASE_GEN4 + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE_GEN4 * bank) + + ADF_RING_CSR_RING_UBASE_GEN4 + (ring << 2)); + + addr = (u64)l_base & 0x00000000FFFFFFFFULL; + addr |= (u64)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define WRITE_CSR_INT_SRCSEL_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_WR((csr_base_addr), \ + ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank) + \ + ADF_RING_CSR_INT_SRCSEL, \ + ADF_BANK_INT_SRC_SEL_MASK_GEN4) + +#define READ_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring) \ + read_base_gen4vf((csr_base_addr), (bank), (ring)) + +#define WRITE_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_HEAD + ((ring) << 2), \ + (value)) +#define WRITE_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_TAIL + ((ring) << 2), \ + (value)) +#define WRITE_CSR_INT_FLAG_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_FLAG, \ + (value)) +#define WRITE_CSR_INT_COL_EN_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_COL_EN, \ + (value)) +#define WRITE_CSR_INT_COL_CTL_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_COL_CTL, \ + (value)) +#define WRITE_CSR_INT_FLAG_AND_COL_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_FLAG_AND_COL, \ + (value)) +#define READ_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_SRV_ARB_EN) +#define WRITE_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_SRV_ARB_EN, \ + (value)) + +struct adf_hw_csr_info; +void gen4vf_init_hw_csr_info(struct adf_hw_csr_info *csr_info); + +#endif /* ADF_GEN4VF_HW_CSR_DATA_H_ */ diff --git a/sys/dev/qat/include/adf_pf2vf_msg.h b/sys/dev/qat/include/adf_pf2vf_msg.h deleted file mode 100644 index 9c8462a8f6b6..000000000000 --- a/sys/dev/qat/include/adf_pf2vf_msg.h +++ /dev/null @@ -1,182 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#ifndef ADF_PF2VF_MSG_H -#define ADF_PF2VF_MSG_H - -/* - * PF<->VF Messaging - * The PF has an array of 32-bit PF2VF registers, one for each VF. The - * PF can access all these registers; each VF can access only the one - * register associated with that particular VF. - * - * The register functionally is split into two parts: - * The bottom half is for PF->VF messages. In particular when the first - * bit of this register (bit 0) gets set an interrupt will be triggered - * in the respective VF. - * The top half is for VF->PF messages. In particular when the first bit - * of this half of register (bit 16) gets set an interrupt will be triggered - * in the PF. - * - * The remaining bits within this register are available to encode messages. - * and implement a collision control mechanism to prevent concurrent use of - * the PF2VF register by both the PF and VF. - * - * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 - * _______________________________________________ - * | | | | | | | | | | | | | | | | | - * +-----------------------------------------------+ - * \___________________________/ \_________/ ^ ^ - * ^ ^ | | - * | | | VF2PF Int - * | | Message Origin - * | Message Type - * Message-specific Data/Reserved - * - * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - * _______________________________________________ - * | | | | | | | | | | | | | | | | | - * +-----------------------------------------------+ - * \___________________________/ \_________/ ^ ^ - * ^ ^ | | - * | | | PF2VF Int - * | | Message Origin - * | Message Type - * Message-specific Data/Reserved - * - * Message Origin (Should always be 1) - * A legacy out-of-tree QAT driver allowed for a set of messages not supported - * by this driver; these had a Msg Origin of 0 and are ignored by this driver. - * - * When a PF or VF attempts to send a message in the lower or upper 16 bits, - * respectively, the other 16 bits are written to first with a defined - * IN_USE_BY pattern as part of a collision control scheme (see adf_iov_putmsg). - */ - -/* VF/PF compatibility version. */ -/* ADF_PFVF_COMPATIBILITY_EXT_CAP: Support for extended capabilities */ -#define ADF_PFVF_COMPATIBILITY_CAPABILITIES 2 -/* ADF_PFVF_COMPATIBILITY_FAST_ACK: In-use pattern cleared by receiver */ -#define ADF_PFVF_COMPATIBILITY_FAST_ACK 3 -#define ADF_PFVF_COMPATIBILITY_RING_TO_SVC_MAP 4 -#define ADF_PFVF_COMPATIBILITY_VERSION 4 /* PF<->VF compat */ - -/* PF->VF messages */ -#define ADF_PF2VF_INT BIT(0) -#define ADF_PF2VF_MSGORIGIN_SYSTEM BIT(1) -#define ADF_PF2VF_MSGTYPE_MASK 0x0000003C -#define ADF_PF2VF_MSGTYPE_SHIFT 2 -#define ADF_PF2VF_MSGTYPE_RESTARTING 0x01 -#define ADF_PF2VF_MSGTYPE_VERSION_RESP 0x02 -#define ADF_PF2VF_MSGTYPE_BLOCK_RESP 0x03 -#define ADF_PF2VF_MSGTYPE_FATAL_ERROR 0x04 -#define ADF_PF2VF_IN_USE_BY_PF 0x6AC20000 -#define ADF_PF2VF_IN_USE_BY_PF_MASK 0xFFFE0000 - -/* PF->VF Version Response */ -#define ADF_PF2VF_VERSION_RESP_VERS_MASK 0x00003FC0 -#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6 -#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x0000C000 -#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14 -#define ADF_PF2VF_MINORVERSION_SHIFT 6 -#define ADF_PF2VF_MAJORVERSION_SHIFT 10 -#define ADF_PF2VF_VF_COMPATIBLE 1 -#define ADF_PF2VF_VF_INCOMPATIBLE 2 -#define ADF_PF2VF_VF_COMPAT_UNKNOWN 3 - -/* PF->VF Block Request Type */ -#define ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE 0 -#define ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE (ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE + 15) -#define ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE (ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE + 1) -#define ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE \ - (ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE + 7) -#define ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE (ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE + 1) -#define ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE (ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE + 3) -#define ADF_VF2PF_SMALL_PAYLOAD_SIZE 30 -#define ADF_VF2PF_MEDIUM_PAYLOAD_SIZE 62 -#define ADF_VF2PF_LARGE_PAYLOAD_SIZE 126 - -#define ADF_VF2PF_MAX_BLOCK_TYPE 3 -#define ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT 22 -#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT 24 -#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT 25 -#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT 26 -#define ADF_VF2PF_BLOCK_REQ_CRC_SHIFT 31 -#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_MASK 0x7F000000 -#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_MASK 0x7E000000 -#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_MASK 0x7C000000 -#define ADF_VF2PF_LARGE_BLOCK_REQ_TYPE_MASK 0xC00000 -#define ADF_VF2PF_MEDIUM_BLOCK_REQ_TYPE_MASK 0x1C00000 -#define ADF_VF2PF_SMALL_BLOCK_REQ_TYPE_MASK 0x3C00000 - -/* PF->VF Block Response Type */ -#define ADF_PF2VF_BLOCK_RESP_TYPE_DATA 0x0 -#define ADF_PF2VF_BLOCK_RESP_TYPE_CRC 0x1 -#define ADF_PF2VF_BLOCK_RESP_TYPE_ERROR 0x2 -#define ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT 6 -#define ADF_PF2VF_BLOCK_RESP_DATA_SHIFT 8 -#define ADF_PF2VF_BLOCK_RESP_TYPE_MASK 0x000000C0 -#define ADF_PF2VF_BLOCK_RESP_DATA_MASK 0x0000FF00 - -/* PF-VF block message header bytes */ -#define ADF_VF2PF_BLOCK_VERSION_BYTE 0 -#define ADF_VF2PF_BLOCK_LEN_BYTE 1 -#define ADF_VF2PF_BLOCK_DATA 2 - -/* PF->VF Block Error Code */ -#define ADF_PF2VF_INVALID_BLOCK_TYPE 0x0 -#define ADF_PF2VF_INVALID_BYTE_NUM_REQ 0x1 -#define ADF_PF2VF_PAYLOAD_TRUNCATED 0x2 -#define ADF_PF2VF_UNSPECIFIED_ERROR 0x3 - -/* VF->PF messages */ -#define ADF_VF2PF_IN_USE_BY_VF 0x00006AC2 -#define ADF_VF2PF_IN_USE_BY_VF_MASK 0x0000FFFE -#define ADF_VF2PF_INT BIT(16) -#define ADF_VF2PF_MSGORIGIN_SYSTEM BIT(17) -#define ADF_VF2PF_MSGTYPE_MASK 0x003C0000 -#define ADF_VF2PF_MSGTYPE_SHIFT 18 -#define ADF_VF2PF_MSGTYPE_INIT 0x3 -#define ADF_VF2PF_MSGTYPE_SHUTDOWN 0x4 -#define ADF_VF2PF_MSGTYPE_VERSION_REQ 0x5 -#define ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ 0x6 -#define ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ 0x7 -#define ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ 0x8 -#define ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ 0x9 -#define ADF_VF2PF_MSGTYPE_NOTIFY 0xa -#define ADF_VF2PF_MSGGENC_RESTARTING_COMPLETE 0x0 - -/* Block message types - * 0..15 - 32 byte message - * 16..23 - 64 byte message - * 24..27 - 128 byte message - * 2 - Get Capability Request message - */ -#define ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY 2 -#define ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ 0x3 - -/* VF->PF Compatible Version Request */ -#define ADF_VF2PF_COMPAT_VER_REQ_SHIFT 22 - -/* How long to wait for far side to acknowledge receipt */ -#define ADF_IOV_MSG_ACK_DELAY_US 5 -#define ADF_IOV_MSG_ACK_EXP_MAX_DELAY_US (5 * 1000) -#define ADF_IOV_MSG_ACK_DELAY_MS 5 -#define ADF_IOV_MSG_ACK_LIN_MAX_DELAY_US (2 * 1000 * 1000) -/* If CSR is busy, how long to delay before retrying */ -#define ADF_IOV_MSG_RETRY_DELAY 5 -#define ADF_IOV_MSG_MAX_RETRIES 10 -/* How long to wait for a response from the other side */ -#define ADF_IOV_MSG_RESP_TIMEOUT 100 -/* How often to retry when there is no response */ -#define ADF_IOV_MSG_RESP_RETRIES 5 - -#define ADF_IOV_RATELIMIT_INTERVAL 8 -#define ADF_IOV_RATELIMIT_BURST 130 - -/* CRC Calculation */ -#define ADF_CRC8_INIT_VALUE 0xFF -/* PF VF message byte shift */ -#define ADF_PFVF_DATA_SHIFT 8 -#define ADF_PFVF_DATA_MASK 0xFF -#endif /* ADF_IOV_MSG_H */ diff --git a/sys/dev/qat/include/adf_pfvf_vf_msg.h b/sys/dev/qat/include/adf_pfvf_vf_msg.h new file mode 100644 index 000000000000..89ed5a740b29 --- /dev/null +++ b/sys/dev/qat/include/adf_pfvf_vf_msg.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_VF_MSG_H +#define ADF_PFVF_VF_MSG_H + +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev); +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev); +int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev); +int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev); +int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev); + +#endif /* ADF_PFVF_VF_MSG_H */ diff --git a/sys/dev/qat/include/common/adf_accel_devices.h b/sys/dev/qat/include/common/adf_accel_devices.h index 9503069ac2a2..225b86a2a7e1 100644 --- a/sys/dev/qat/include/common/adf_accel_devices.h +++ b/sys/dev/qat/include/common/adf_accel_devices.h @@ -6,6 +6,7 @@ #include "qat_freebsd.h" #include "adf_cfg_common.h" +#include "adf_pfvf_msg.h" #define ADF_CFG_NUM_SERVICES 4 @@ -20,6 +21,7 @@ #define ADF_C4XXX_DEVICE_NAME "c4xxx" #define ADF_C4XXXVF_DEVICE_NAME "c4xxxvf" #define ADF_4XXX_DEVICE_NAME "4xxx" +#define ADF_4XXXVF_DEVICE_NAME "4xxxvf" #define ADF_DH895XCC_PCI_DEVICE_ID 0x435 #define ADF_DH895XCCIOV_PCI_DEVICE_ID 0x443 #define ADF_C62X_PCI_DEVICE_ID 0x37c8 @@ -33,13 +35,17 @@ #define ADF_C4XXX_PCI_DEVICE_ID 0x18a0 #define ADF_C4XXXIOV_PCI_DEVICE_ID 0x18a1 #define ADF_4XXX_PCI_DEVICE_ID 0x4940 +#define ADF_4XXXIOV_PCI_DEVICE_ID 0x4941 #define ADF_401XX_PCI_DEVICE_ID 0x4942 +#define ADF_401XXIOV_PCI_DEVICE_ID 0x4943 #define IS_QAT_GEN3(ID) ({ (ID == ADF_C4XXX_PCI_DEVICE_ID); }) static inline bool IS_QAT_GEN4(const unsigned int id) { - return (id == ADF_4XXX_PCI_DEVICE_ID || id == ADF_401XX_PCI_DEVICE_ID); + return (id == ADF_4XXX_PCI_DEVICE_ID || id == ADF_401XX_PCI_DEVICE_ID || + id == ADF_4XXXIOV_PCI_DEVICE_ID || + id == ADF_401XXIOV_PCI_DEVICE_ID); } #define IS_QAT_GEN3_OR_GEN4(ID) (IS_QAT_GEN3(ID) || IS_QAT_GEN4(ID)) @@ -85,7 +91,7 @@ IS_QAT_GEN4(const unsigned int id) (((ena_srv_mask) >> (ADF_SRV_TYPE_BIT_LEN * (srv))) & ADF_SRV_TYPE_MASK) #define GET_CSR_OPS(accel_dev) (&(accel_dev)->hw_device->csr_info.csr_ops) - +#define GET_PFVF_OPS(accel_dev) (&(accel_dev)->hw_device->csr_info.pfvf_ops) #define ADF_DEFAULT_RING_TO_SRV_MAP \ (CRYPTO | CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ NA << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ @@ -266,6 +272,9 @@ struct adf_hw_csr_ops { u32 bank, u32 ring, u32 value); + bus_addr_t (*read_csr_ring_base)(struct resource *csr_base_addr, + u32 bank, + u32 ring); void (*write_csr_ring_base)(struct resource *csr_base_addr, u32 bank, u32 ring, @@ -288,15 +297,9 @@ struct adf_hw_csr_ops { void (*write_csr_ring_srv_arb_en)(struct resource *csr_base_addr, u32 bank, u32 value); -}; - -struct adf_hw_csr_info { - struct adf_hw_csr_ops csr_ops; - u32 csr_addr_offset; - u32 ring_bundle_size; - u32 bank_int_flag_clear_mask; - u32 num_rings_per_int_srcsel; - u32 arb_enable_mask; + u32 (*get_src_sel_mask)(void); + u32 (*get_int_col_ctl_enable_mask)(void); + u32 (*get_bank_irq_mask)(u32 irq_mask); }; struct adf_cfg_device_data; @@ -304,6 +307,33 @@ struct adf_accel_dev; struct adf_etr_data; struct adf_etr_ring_data; +struct adf_pfvf_ops { + int (*enable_comms)(struct adf_accel_dev *accel_dev); + u32 (*get_pf2vf_offset)(u32 i); + u32 (*get_vf2pf_offset)(u32 i); + void (*enable_vf2pf_interrupts)(struct resource *pmisc_addr, + u32 vf_mask); + void (*disable_all_vf2pf_interrupts)(struct resource *pmisc_addr); + u32 (*disable_pending_vf2pf_interrupts)(struct resource *pmisc_addr); + int (*send_msg)(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + u32 pfvf_offset, + struct mutex *csr_lock); + struct pfvf_message (*recv_msg)(struct adf_accel_dev *accel_dev, + u32 pfvf_offset, + u8 compat_ver); +}; + +struct adf_hw_csr_info { + struct adf_hw_csr_ops csr_ops; + struct adf_pfvf_ops pfvf_ops; + u32 csr_addr_offset; + u32 ring_bundle_size; + u32 bank_int_flag_clear_mask; + u32 num_rings_per_int_srcsel; + u32 arb_enable_mask; +}; + struct adf_hw_device_data { struct adf_hw_device_class *dev_class; uint32_t (*get_accel_mask)(struct adf_accel_dev *accel_dev); @@ -315,9 +345,6 @@ struct adf_hw_device_data { uint32_t (*get_num_accels)(struct adf_hw_device_data *self); void (*notify_and_wait_ethernet)(struct adf_accel_dev *accel_dev); bool (*get_eth_doorbell_msg)(struct adf_accel_dev *accel_dev); - uint32_t (*get_pf2vf_offset)(uint32_t i); - uint32_t (*get_vintmsk_offset)(uint32_t i); - u32 (*get_vintsou_offset)(void); void (*get_arb_info)(struct arb_info *arb_csrs_info); void (*get_admin_info)(struct admin_info *admin_csrs_info); void (*get_errsou_offset)(u32 *errsou3, u32 *errsou5); @@ -352,6 +379,8 @@ struct adf_hw_device_data { const uint32_t **cfg); int (*init_device)(struct adf_accel_dev *accel_dev); int (*get_heartbeat_status)(struct adf_accel_dev *accel_dev); + int (*int_timer_init)(struct adf_accel_dev *accel_dev); + void (*int_timer_exit)(struct adf_accel_dev *accel_dev); uint32_t (*get_ae_clock)(struct adf_hw_device_data *self); uint32_t (*get_hb_clock)(struct adf_hw_device_data *self); void (*disable_iov)(struct adf_accel_dev *accel_dev); @@ -360,8 +389,10 @@ struct adf_hw_device_data { void (*enable_ints)(struct adf_accel_dev *accel_dev); bool (*check_slice_hang)(struct adf_accel_dev *accel_dev); int (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev); - int (*enable_vf2pf_comms)(struct adf_accel_dev *accel_dev); - int (*disable_vf2pf_comms)(struct adf_accel_dev *accel_dev); + void (*enable_pf2vf_interrupt)(struct adf_accel_dev *accel_dev); + void (*disable_pf2vf_interrupt)(struct adf_accel_dev *accel_dev); + int (*interrupt_active_pf2vf)(struct adf_accel_dev *accel_dev); + int (*get_int_active_bundles)(struct adf_accel_dev *accel_dev); void (*reset_device)(struct adf_accel_dev *accel_dev); void (*reset_hw_units)(struct adf_accel_dev *accel_dev); int (*measure_clock)(struct adf_accel_dev *accel_dev); @@ -378,6 +409,11 @@ struct adf_hw_device_data { char *aeidstr); void (*remove_misc_error)(struct adf_accel_dev *accel_dev); int (*configure_accel_units)(struct adf_accel_dev *accel_dev); + int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, + u32 bank_number); + void (*config_ring_irq)(struct adf_accel_dev *accel_dev, + u32 bank_number, + u16 ring_mask); uint32_t (*get_objs_num)(struct adf_accel_dev *accel_dev); const char *(*get_obj_name)(struct adf_accel_dev *accel_dev, enum adf_accel_unit_services services); @@ -411,7 +447,6 @@ struct adf_hw_device_data { uint8_t num_accel; uint8_t num_logical_accel; uint8_t num_engines; - uint8_t min_iov_compat_ver; int (*get_storage_enabled)(struct adf_accel_dev *accel_dev, uint32_t *storage_enabled); u8 query_storage_cap; @@ -419,6 +454,7 @@ struct adf_hw_device_data { u8 storage_enable; u32 extended_dc_capabilities; int (*config_device)(struct adf_accel_dev *accel_dev); + u32 asym_ae_active_thd_mask; u16 asym_rings_mask; int (*get_fw_image_type)(struct adf_accel_dev *accel_dev, enum adf_cfg_fw_image_type *fw_image_type); @@ -603,6 +639,15 @@ struct adf_fw_versions { u8 mmp_version_patch; }; +struct adf_int_timer { + struct adf_accel_dev *accel_dev; + struct workqueue_struct *timer_irq_wq; + struct timer_list timer; + u32 timeout_val; + u32 int_cnt; + bool enabled; +}; + #define ADF_COMPAT_CHECKER_MAX 8 typedef int (*adf_iov_compat_checker_t)(struct adf_accel_dev *accel_dev, u8 vf_compat_ver); @@ -620,7 +665,9 @@ struct adf_accel_dev { struct adf_cfg_device_data *cfg; struct adf_fw_loader_data *fw_loader; struct adf_admin_comms *admin; + struct adf_uio_control_accel *accel; struct adf_heartbeat *heartbeat; + struct adf_int_timer *int_timer; struct adf_fw_versions fw_versions; unsigned int autoreset_on_error; struct adf_fw_counters_data *fw_counters_data; @@ -648,17 +695,18 @@ struct adf_accel_dev { int num_vfs; } pf; struct { + bool irq_enabled; struct resource *irq; void *cookie; - char *irq_name; struct task pf2vf_bh_tasklet; struct mutex vf2pf_lock; /* protect CSR access */ - int iov_msg_completion; - uint8_t compatible; - uint8_t pf_version; - u8 pf2vf_block_byte; - u8 pf2vf_block_resp_type; + struct completion msg_received; + struct pfvf_message + response; /* temp field holding pf2vf response */ + enum ring_reset_result rpreset_sts; + struct mutex rpreset_lock; /* protect rpreset_sts */ struct pfvf_stats pfvf_counters; + u8 pf_compat_ver; } vf; } u1; bool is_vf; diff --git a/sys/dev/qat/include/common/adf_cfg.h b/sys/dev/qat/include/common/adf_cfg.h index 58502c8605b8..a3ac7678a7a8 100644 --- a/sys/dev/qat/include/common/adf_cfg.h +++ b/sys/dev/qat/include/common/adf_cfg.h @@ -9,6 +9,8 @@ #include "adf_cfg_common.h" #include "adf_cfg_strings.h" +#define ADF_CFG_MAX_VAL 16 + struct adf_cfg_key_val { char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; @@ -29,6 +31,9 @@ struct adf_cfg_device_data { struct list_head sec_list; struct sysctl_oid *debug; struct sx lock; + char cfg_services[ADF_CFG_MAX_VAL]; + char cfg_mode[ADF_CFG_MAX_VAL]; + u16 num_user_processes; }; struct adf_cfg_depot_list { diff --git a/sys/dev/qat/include/common/adf_cfg_common.h b/sys/dev/qat/include/common/adf_cfg_common.h index 65fc60fc8c3d..d8b1efe3dbe6 100644 --- a/sys/dev/qat/include/common/adf_cfg_common.h +++ b/sys/dev/qat/include/common/adf_cfg_common.h @@ -88,7 +88,10 @@ enum adf_device_type { DEV_200XXVF, DEV_C4XXX, DEV_C4XXXVF, - DEV_4XXX + DEV_D15XX, + DEV_D15XXVF, + DEV_4XXX, + DEV_4XXXVF }; enum adf_cfg_fw_image_type { @@ -196,9 +199,23 @@ struct adf_cfg_instance { #define ADF_CFG_DEF_ASYM_MASK 0x03 #define ADF_CFG_MAX_SERVICES 4 +#define ADF_CTL_IOC_MAGIC 'a' +#define IOCTL_STATUS_ACCEL_DEV \ + _IOWR(ADF_CTL_IOC_MAGIC, 3, struct adf_dev_status_info) +#define IOCTL_RESERVE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 10, struct adf_user_reserve_ring) +#define IOCTL_RELEASE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 11, struct adf_user_reserve_ring) +#define IOCTL_ENABLE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 12, struct adf_user_reserve_ring) +#define IOCTL_DISABLE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 13, struct adf_user_reserve_ring) +#define IOCTL_GET_NUM_DEVICES _IOR(ADF_CTL_IOC_MAGIC, 4, int32_t) #define ADF_CFG_HB_DEFAULT_VALUE 500 #define ADF_CFG_HB_COUNT_THRESHOLD 3 #define ADF_MIN_HB_TIMER_MS 100 +#define IOCTL_GET_CFG_VAL \ + _IOW(ADF_CTL_IOC_MAGIC, 5, struct adf_user_cfg_ctl_data) enum adf_device_heartbeat_status { DEV_HB_UNRESPONSIVE = 0, @@ -210,4 +227,6 @@ struct adf_dev_heartbeat_status_ctl { uint16_t device_id; enum adf_device_heartbeat_status status; }; +#define IOCTL_HEARTBEAT_ACCEL_DEV \ + _IOWR(ADF_CTL_IOC_MAGIC, 9, struct adf_dev_heartbeat_status_ctl) #endif diff --git a/sys/dev/qat/include/common/adf_cfg_strings.h b/sys/dev/qat/include/common/adf_cfg_strings.h index 933ffe0ba6ad..5d39fd6cdc3f 100644 --- a/sys/dev/qat/include/common/adf_cfg_strings.h +++ b/sys/dev/qat/include/common/adf_cfg_strings.h @@ -7,6 +7,7 @@ #define ADF_GENERAL_SEC "GENERAL" #define ADF_KERNEL_SEC "KERNEL" #define ADF_ACCEL_SEC "Accelerator" +#define ADF_SAL_SEC "SSL" #define ADF_NUM_CY "NumberCyInstances" #define ADF_NUM_DC "NumberDcInstances" #define ADF_RING_SYM_SIZE "NumConcurrentSymRequests" @@ -55,6 +56,11 @@ #define ADF_CFG_DC "dc" #define ADF_CFG_ASYM "asym" #define ADF_CFG_SYM "sym" +#define ADF_CFG_SYM_ASYM "sym;asym" +#define ADF_CFG_SYM_DC "sym;dc" +#define ADF_CFG_KERNEL_USER "ks;us" +#define ADF_CFG_KERNEL "ks" +#define ADF_CFG_USER "us" #define ADF_SERVICE_INLINE "inline" #define ADF_SERVICES_ENABLED "ServicesEnabled" #define ADF_SERVICES_SEPARATOR ";" diff --git a/sys/dev/qat/include/common/adf_cfg_sysctl.h b/sys/dev/qat/include/common/adf_cfg_sysctl.h new file mode 100644 index 000000000000..d6a7183c039a --- /dev/null +++ b/sys/dev/qat/include/common/adf_cfg_sysctl.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_CFG_SYSCTL_H_ +#define ADF_CFG_SYSCTL_H_ + +#include "adf_accel_devices.h" + +int adf_cfg_sysctl_add(struct adf_accel_dev *accel_dev); +void adf_cfg_sysctl_remove(struct adf_accel_dev *accel_dev); + +#endif /* ADF_CFG_SYSCTL_H_ */ diff --git a/sys/dev/qat/include/common/adf_common_drv.h b/sys/dev/qat/include/common/adf_common_drv.h index 7ec380540336..0c8bb565f748 100644 --- a/sys/dev/qat/include/common/adf_common_drv.h +++ b/sys/dev/qat/include/common/adf_common_drv.h @@ -9,7 +9,10 @@ #include "icp_qat_fw_loader_handle.h" #include "icp_qat_hal.h" #include "adf_cfg_user.h" +#include "adf_uio.h" +#include "adf_uio_control.h" +#define QAT_UIO_IOC_MAGIC 'b' #define ADF_MAJOR_VERSION 0 #define ADF_MINOR_VERSION 6 #define ADF_BUILD_VERSION 0 @@ -17,6 +20,10 @@ __stringify(ADF_MAJOR_VERSION) "." __stringify( \ ADF_MINOR_VERSION) "." __stringify(ADF_BUILD_VERSION) +#define IOCTL_GET_BUNDLE_SIZE _IOR(QAT_UIO_IOC_MAGIC, 0, int32_t) +#define IOCTL_ALLOC_BUNDLE _IOW(QAT_UIO_IOC_MAGIC, 1, int) +#define IOCTL_GET_ACCEL_TYPE _IOR(QAT_UIO_IOC_MAGIC, 2, uint32_t) +#define IOCTL_ADD_MEM_FD _IOW(QAT_UIO_IOC_MAGIC, 3, int) #define ADF_STATUS_RESTARTING 0 #define ADF_STATUS_STARTING 1 #define ADF_STATUS_CONFIGURED 2 @@ -81,43 +88,7 @@ int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, void adf_error_notifier(uintptr_t arg); int adf_init_fatal_error_wq(void); void adf_exit_fatal_error_wq(void); -int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); -int adf_iov_notify(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); -void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); int adf_notify_fatal_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_uncorrectable_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_heartbeat_error(struct adf_accel_dev *accel_dev); -typedef int (*adf_iov_block_provider)(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num); -int adf_iov_block_provider_register(u8 block_type, - const adf_iov_block_provider provider); -u8 adf_iov_is_block_provider_registered(u8 block_type); -int adf_iov_block_provider_unregister(u8 block_type, - const adf_iov_block_provider provider); -int adf_iov_block_get(struct adf_accel_dev *accel_dev, - u8 block_type, - u8 *block_version, - u8 *buffer, - u8 *length); -u8 adf_pfvf_crc(u8 start_crc, u8 *buf, u8 len); -int adf_iov_init_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm); -int adf_iov_shutdown_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm); -int adf_iov_register_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc); -int adf_iov_unregister_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc); -int adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_pf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev); -void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info); void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); void adf_clean_vf_map(bool); int adf_sysctl_add_fw_versions(struct adf_accel_dev *accel_dev); @@ -125,19 +96,12 @@ int adf_sysctl_remove_fw_versions(struct adf_accel_dev *accel_dev); int adf_ctl_dev_register(void); void adf_ctl_dev_unregister(void); -int adf_pf_vf_capabilities_init(struct adf_accel_dev *accel_dev); -int adf_pf_ext_dc_cap_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility); -int adf_pf_vf_ring_to_svc_init(struct adf_accel_dev *accel_dev); -int adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num); +int adf_register_ctl_device_driver(void); +void adf_unregister_ctl_device_driver(void); +int adf_processes_dev_register(void); +void adf_processes_dev_unregister(void); +void adf_state_init(void); +void adf_state_destroy(void); int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, struct adf_accel_dev *pf); void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev, @@ -212,6 +176,7 @@ void adf_disable_ring_arb(struct adf_accel_dev *accel_dev, unsigned int bank_nr, unsigned int mask); int adf_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); +void adf_update_uio_ring_arb(struct adf_uio_control_bundle *bundle); struct adf_accel_dev *adf_devmgr_get_dev_by_bdf(struct adf_pci_address *addr); struct adf_accel_dev *adf_devmgr_get_dev_by_pci_bus(u8 bus); int adf_get_vf_nr(struct adf_pci_address *vf_pci_addr, int *vf_nr); @@ -239,7 +204,7 @@ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev); void adf_isr_resource_free(struct adf_accel_dev *accel_dev); int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev); void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev); - +int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev); int qat_hal_init(struct adf_accel_dev *accel_dev); void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle); int qat_hal_start(struct icp_qat_fw_loader_handle *handle); @@ -334,13 +299,13 @@ int qat_uclo_map_obj(struct icp_qat_fw_loader_handle *handle, void qat_hal_get_scs_neigh_ae(unsigned char ae, unsigned char *ae_neigh); int qat_uclo_set_cfg_ae_mask(struct icp_qat_fw_loader_handle *handle, unsigned int cfg_ae_mask); -void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); -void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); int adf_init_vf_wq(void); void adf_exit_vf_wq(void); -void adf_flush_vf_wq(void); -int adf_vf2pf_init(struct adf_accel_dev *accel_dev); -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev); +void adf_flush_vf_wq(struct adf_accel_dev *accel_dev); +int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev); +int adf_pf2vf_handle_pf_rp_reset(struct adf_accel_dev *accel_dev, + struct pfvf_message msg); +bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev); static inline int adf_sriov_configure(device_t *pdev, int numvfs) { diff --git a/sys/dev/qat/include/common/adf_gen2_hw_data.h b/sys/dev/qat/include/common/adf_gen2_hw_data.h index 395abec81b9f..cabfa6c9e5ff 100644 --- a/sys/dev/qat/include/common/adf_gen2_hw_data.h +++ b/sys/dev/qat/include/common/adf_gen2_hw_data.h @@ -23,6 +23,7 @@ #define ADF_RING_CSR_INT_COL_CTL 0x180 #define ADF_RING_CSR_INT_FLAG_AND_COL 0x184 #define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000 +#define ADF_RING_CSR_ADDR_OFFSET 0x0 #define ADF_RING_BUNDLE_SIZE 0x1000 #define ADF_GEN2_RX_RINGS_OFFSET 8 #define ADF_GEN2_TX_RINGS_MASK 0xFF @@ -45,6 +46,29 @@ (ADF_RING_BUNDLE_SIZE * (bank)) + \ ADF_RING_CSR_RING_CONFIG + ((ring) << 2), \ value) + +static inline uint64_t +read_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_LBASE + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_UBASE + (ring << 2)); + + addr = (uint64_t)l_base & 0x00000000FFFFFFFFULL; + addr |= (uint64_t)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define READ_CSR_RING_BASE(csr_base_addr, bank, ring) \ + read_base(csr_base_addr, bank, ring) + #define WRITE_CSR_RING_BASE(csr_base_addr, bank, ring, value) \ do { \ u32 l_base = 0, u_base = 0; \ diff --git a/sys/dev/qat/include/common/adf_gen4_hw_data.h b/sys/dev/qat/include/common/adf_gen4_hw_data.h index c0ef0c92772e..c2c375f8a401 100644 --- a/sys/dev/qat/include/common/adf_gen4_hw_data.h +++ b/sys/dev/qat/include/common/adf_gen4_hw_data.h @@ -23,6 +23,22 @@ #define ADF_RING_CSR_ADDR_OFFSET 0x100000 #define ADF_RING_BUNDLE_SIZE 0x2000 +/* Ring reset */ +#define ADF_RPRESET_POLL_TIMEOUT_US (5 * USEC_PER_SEC) +#define ADF_RPRESET_POLL_DELAY_US 20 +#define ADF_WQM_CSR_RPRESETCTL_RESET BIT(0) +#define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3)) +#define ADF_WQM_CSR_RPRESETSTS_STATUS BIT(0) +#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4) + +#define ADF_WQM_CSR_RPRESETCTL_SHIFT 0 +#define ADF_WQM_CSR_RPRESETCTL_DRAIN_SHIFT 2 +#define ADF_WQM_CSR_RPRESETCTL_MASK (BIT(3) - 1) +#define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3)) +#define ADF_WQM_CSR_RPRESETSTS_SHIFT 0 +#define ADF_WQM_CSR_RPRESETSTS_MASK (BIT(0)) +#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4) + #define BUILD_RING_BASE_ADDR(addr, size) \ ((((addr) >> 6) & (GENMASK_ULL(63, 0) << (size))) << 6) #define READ_CSR_RING_HEAD(csr_base_addr, bank, ring) \ @@ -63,6 +79,30 @@ u_base); \ } while (0) +static inline u64 +read_base_gen4(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + ADF_RING_CSR_ADDR_OFFSET + + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_LBASE + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + ADF_RING_CSR_ADDR_OFFSET + + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_UBASE + (ring << 2)); + + addr = (u64)l_base & 0x00000000FFFFFFFFULL; + addr |= (u64)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define READ_CSR_RING_BASE(csr_base_addr, bank, ring) \ + read_base_gen4((csr_base_addr), (bank), (ring)) + #define WRITE_CSR_RING_HEAD(csr_base_addr, bank, ring, value) \ ADF_CSR_WR((csr_base_addr), \ ADF_RING_CSR_ADDR_OFFSET + ADF_RING_BUNDLE_SIZE * (bank) + \ @@ -129,4 +169,5 @@ int adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); void adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info); +int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number); #endif diff --git a/sys/dev/qat/include/common/adf_pfvf_msg.h b/sys/dev/qat/include/common/adf_pfvf_msg.h new file mode 100644 index 000000000000..b0f3feb7d398 --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_msg.h @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_MSG_H +#define ADF_PFVF_MSG_H + +/* + * PF<->VF Gen2 Messaging format + * + * The PF has an array of 32-bit PF2VF registers, one for each VF. The + * PF can access all these registers while each VF can access only the one + * register associated with that particular VF. + * + * The register functionally is split into two parts: + * The bottom half is for PF->VF messages. In particular when the first + * bit of this register (bit 0) gets set an interrupt will be triggered + * in the respective VF. + * The top half is for VF->PF messages. In particular when the first bit + * of this half of register (bit 16) gets set an interrupt will be triggered + * in the PF. + * + * The remaining bits within this register are available to encode messages. + * and implement a collision control mechanism to prevent concurrent use of + * the PF2VF register by both the PF and VF. + * + * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 + * _______________________________________________ + * | | | | | | | | | | | | | | | | | + * +-----------------------------------------------+ + * \___________________________/ \_________/ ^ ^ + * ^ ^ | | + * | | | VF2PF Int + * | | Message Origin + * | Message Type + * Message-specific Data/Reserved + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * _______________________________________________ + * | | | | | | | | | | | | | | | | | + * +-----------------------------------------------+ + * \___________________________/ \_________/ ^ ^ + * ^ ^ | | + * | | | PF2VF Int + * | | Message Origin + * | Message Type + * Message-specific Data/Reserved + * + * Message Origin (Should always be 1) + * A legacy out-of-tree QAT driver allowed for a set of messages not supported + * by this driver; these had a Msg Origin of 0 and are ignored by this driver. + * + * When a PF or VF attempts to send a message in the lower or upper 16 bits, + * respectively, the other 16 bits are written to first with a defined + * IN_USE_BY pattern as part of a collision control scheme (see function + * adf_gen2_pfvf_send() in adf_pf2vf_msg.c). + * + * + * PF<->VF Gen4 Messaging format + * + * Similarly to the gen2 messaging format, 32-bit long registers are used for + * communication between PF and VFs. However, each VF and PF share a pair of + * 32-bits register to avoid collisions: one for PV to VF messages and one + * for VF to PF messages. + * + * Both the Interrupt bit and the Message Origin bit retain the same position + * and meaning, although non-system messages are now deprecated and not + * expected. + * + * 31 30 9 8 7 6 5 4 3 2 1 0 + * _______________________________________________ + * | | | . . . | | | | | | | | | | | + * +-----------------------------------------------+ + * \_____________________/ \_______________/ ^ ^ + * ^ ^ | | + * | | | PF/VF Int + * | | Message Origin + * | Message Type + * Message-specific Data/Reserved + * + * For both formats, the message reception is acknowledged by lowering the + * interrupt bit on the register where the message was sent. + */ + +/* PFVF message common bits */ +#define ADF_PFVF_INT BIT(0) +#define ADF_PFVF_MSGORIGIN_SYSTEM BIT(1) + +/* Different generations have different CSR layouts, use this struct + * to abstract these differences away + */ +struct pfvf_message { + u8 type; + u32 data; +}; + +/* PF->VF messages */ +enum pf2vf_msgtype { + ADF_PF2VF_MSGTYPE_RESTARTING = 0x01, + ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02, + ADF_PF2VF_MSGTYPE_BLKMSG_RESP = 0x03, + /* Values from 0x10 are Gen4 specific, message type is only 4 bits in + Gen2 devices. */ + ADF_PF2VF_MSGTYPE_RP_RESET_RESP = 0x10, +}; + +/* VF->PF messages */ +enum vf2pf_msgtype { + ADF_VF2PF_MSGTYPE_INIT = 0x03, + ADF_VF2PF_MSGTYPE_SHUTDOWN = 0x04, + ADF_VF2PF_MSGTYPE_VERSION_REQ = 0x05, + ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ = 0x06, + ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ = 0x07, + ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ = 0x08, + ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ = 0x09, + /* Values from 0x10 are Gen4 specific, message type is only 4 bits in + Gen2 devices. */ + ADF_VF2PF_MSGTYPE_RP_RESET = 0x10, +}; + +/* VF/PF compatibility version. */ +enum pfvf_compatibility_version { + /* Support for extended capabilities */ + ADF_PFVF_COMPAT_CAPABILITIES = 0x02, + /* In-use pattern cleared by receiver */ + ADF_PFVF_COMPAT_FAST_ACK = 0x03, + /* Ring to service mapping support for non-standard mappings */ + ADF_PFVF_COMPAT_RING_TO_SVC_MAP = 0x04, + /* Reference to the latest version */ + ADF_PFVF_COMPAT_THIS_VERSION = 0x04, +}; + +/* PF->VF Version Response */ +#define ADF_PF2VF_VERSION_RESP_VERS_MASK GENMASK(7, 0) +#define ADF_PF2VF_VERSION_RESP_RESULT_MASK GENMASK(9, 8) + +enum pf2vf_compat_response { + ADF_PF2VF_VF_COMPATIBLE = 0x01, + ADF_PF2VF_VF_INCOMPATIBLE = 0x02, + ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03, +}; + +enum ring_reset_result { + RPRESET_SUCCESS = 0x00, + RPRESET_NOT_SUPPORTED = 0x01, + RPRESET_INVAL_BANK = 0x02, + RPRESET_TIMEOUT = 0x03, +}; + +#define ADF_VF2PF_RNG_RESET_RP_MASK GENMASK(1, 0) +#define ADF_VF2PF_RNG_RESET_RSVD_MASK GENMASK(25, 2) + +/* PF->VF Block Responses */ +#define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK GENMASK(1, 0) +#define ADF_PF2VF_BLKMSG_RESP_DATA_MASK GENMASK(9, 2) + +enum pf2vf_blkmsg_resp_type { + ADF_PF2VF_BLKMSG_RESP_TYPE_DATA = 0x00, + ADF_PF2VF_BLKMSG_RESP_TYPE_CRC = 0x01, + ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR = 0x02, +}; + +/* PF->VF Block Error Code */ +enum pf2vf_blkmsg_error { + ADF_PF2VF_INVALID_BLOCK_TYPE = 0x00, + ADF_PF2VF_INVALID_BYTE_NUM_REQ = 0x01, + ADF_PF2VF_PAYLOAD_TRUNCATED = 0x02, + ADF_PF2VF_UNSPECIFIED_ERROR = 0x03, +}; + +/* VF->PF Block Requests */ +#define ADF_VF2PF_LARGE_BLOCK_TYPE_MASK GENMASK(1, 0) +#define ADF_VF2PF_LARGE_BLOCK_BYTE_MASK GENMASK(8, 2) +#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK GENMASK(2, 0) +#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK GENMASK(8, 3) +#define ADF_VF2PF_SMALL_BLOCK_TYPE_MASK GENMASK(3, 0) +#define ADF_VF2PF_SMALL_BLOCK_BYTE_MASK GENMASK(8, 4) +#define ADF_VF2PF_BLOCK_CRC_REQ_MASK BIT(9) + +/* PF->VF Block Request Types + * 0..15 - 32 byte message + * 16..23 - 64 byte message + * 24..27 - 128 byte message + */ +enum vf2pf_blkmsg_req_type { + ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY = 0x02, + ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP = 0x03, +}; + +#define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \ + (FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK)) + +#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX \ + (FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK) + \ + ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1) + +#define ADF_VF2PF_LARGE_BLOCK_TYPE_MAX \ + (FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK) + \ + ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) + +#define ADF_VF2PF_SMALL_BLOCK_BYTE_MAX \ + FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK) + +#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX \ + FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK) + +#define ADF_VF2PF_LARGE_BLOCK_BYTE_MAX \ + FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK) + +struct pfvf_blkmsg_header { + u8 version; + u8 payload_size; +} __packed; + +#define ADF_PFVF_BLKMSG_HEADER_SIZE (sizeof(struct pfvf_blkmsg_header)) +#define ADF_PFVF_BLKMSG_PAYLOAD_SIZE(blkmsg) \ + (sizeof(blkmsg) - ADF_PFVF_BLKMSG_HEADER_SIZE) +#define ADF_PFVF_BLKMSG_MSG_SIZE(blkmsg) \ + (ADF_PFVF_BLKMSG_HEADER_SIZE + (blkmsg)->hdr.payload_size) +#define ADF_PFVF_BLKMSG_MSG_MAX_SIZE 128 + +/* PF->VF Block message header bytes */ +#define ADF_PFVF_BLKMSG_VER_BYTE 0 +#define ADF_PFVF_BLKMSG_LEN_BYTE 1 + +/* PF/VF Capabilities message values */ +enum blkmsg_capabilities_versions { + ADF_PFVF_CAPABILITIES_V1_VERSION = 0x01, + ADF_PFVF_CAPABILITIES_V2_VERSION = 0x02, + ADF_PFVF_CAPABILITIES_V3_VERSION = 0x03, +}; + +struct capabilities_v1 { + struct pfvf_blkmsg_header hdr; + u32 ext_dc_caps; +} __packed; + +struct capabilities_v2 { + struct pfvf_blkmsg_header hdr; + u32 ext_dc_caps; + u32 capabilities; +} __packed; + +struct capabilities_v3 { + struct pfvf_blkmsg_header hdr; + u32 ext_dc_caps; + u32 capabilities; + u32 frequency; +} __packed; + +/* PF/VF Ring to service mapping values */ +enum blkmsg_ring_to_svc_versions { + ADF_PFVF_RING_TO_SVC_VERSION = 0x01, +}; + +struct ring_to_svc_map_v1 { + struct pfvf_blkmsg_header hdr; + u16 map; +} __packed; + +#endif /* ADF_PFVF_MSG_H */ diff --git a/sys/dev/qat/include/common/adf_pfvf_utils.h b/sys/dev/qat/include/common/adf_pfvf_utils.h new file mode 100644 index 000000000000..43eb7b52ef6b --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_utils.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_UTILS_H +#define ADF_PFVF_UTILS_H + +#include +#include "adf_pfvf_msg.h" + +/* How long to wait for far side to acknowledge receipt */ +#define ADF_PFVF_MSG_ACK_DELAY_US 4 +#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (1 * USEC_PER_SEC) + +u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len); + +struct pfvf_field_format { + u8 offset; + u32 mask; +}; + +struct pfvf_csr_format { + struct pfvf_field_format type; + struct pfvf_field_format data; +}; + +u32 adf_pfvf_csr_msg_of(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + const struct pfvf_csr_format *fmt); +struct pfvf_message adf_pfvf_message_of(struct adf_accel_dev *accel_dev, + u32 raw_msg, + const struct pfvf_csr_format *fmt); + +static inline struct resource * +adf_get_pmisc_base(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + struct adf_bar *pmisc; + + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + + return pmisc->virt_addr; +} + +#endif /* ADF_PFVF_UTILS_H */ diff --git a/sys/dev/qat/include/common/adf_pfvf_vf_proto.h b/sys/dev/qat/include/common/adf_pfvf_vf_proto.h new file mode 100644 index 000000000000..f2623c1730bb --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_vf_proto.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_VF_PROTO_H +#define ADF_PFVF_VF_PROTO_H + +#include +#include "adf_accel_devices.h" + +#define ADF_PFVF_MSG_COLLISION_DETECT_DELAY 10 +#define ADF_PFVF_MSG_ACK_DELAY 2 +#define ADF_PFVF_MSG_ACK_MAX_RETRY 100 + +/* How often to retry if there is no response */ +#define ADF_PFVF_MSG_RESP_RETRIES 5 +#define ADF_PFVF_MSG_RESP_TIMEOUT \ + (ADF_PFVF_MSG_ACK_DELAY * ADF_PFVF_MSG_ACK_MAX_RETRY + \ + ADF_PFVF_MSG_COLLISION_DETECT_DELAY) + +int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, + struct pfvf_message msg); +int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + struct pfvf_message *resp); +int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, + u8 type, + u8 *buffer, + unsigned int *buffer_len); + +int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); + +#endif /* ADF_PFVF_VF_PROTO_H */ diff --git a/sys/dev/qat/include/common/adf_uio.h b/sys/dev/qat/include/common/adf_uio.h new file mode 100644 index 000000000000..07d33054c74b --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_UIO_H +#define ADF_UIO_H +#include "adf_accel_devices.h" + +struct qat_uio_bundle_dev { + u8 hardware_bundle_number; + struct adf_uio_control_bundle *bundle; + struct adf_uio_control_accel *accel; +}; + +int adf_uio_register(struct adf_accel_dev *accel_dev); +void adf_uio_remove(struct adf_accel_dev *accel_dev); + +#endif /* end of include guard: ADF_UIO_H */ diff --git a/sys/dev/qat/include/common/adf_uio_cleanup.h b/sys/dev/qat/include/common/adf_uio_cleanup.h new file mode 100644 index 000000000000..d8c59f74935b --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio_cleanup.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_UIO_CLEANUP_H +#define ADF_UIO_CLEANUP_H + +void adf_uio_do_cleanup_orphan(int bank, + struct adf_uio_control_accel *accel); + + +#endif diff --git a/sys/dev/qat/include/common/adf_uio_control.h b/sys/dev/qat/include/common/adf_uio_control.h new file mode 100644 index 000000000000..0572a12764b6 --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio_control.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef QAT_UIO_CONTROL_H +#define QAT_UIO_CONTROL_H +#include + +struct adf_uio_instance_rings { + unsigned int user_pid; + u16 ring_mask; + struct list_head list; +}; + +struct adf_uio_control_bundle { + uint8_t hardware_bundle_number; + bool used; + struct list_head list; + struct mutex list_lock; /* protects list struct */ + struct mutex lock; /* protects rings_used and csr_addr */ + u16 rings_used; + u32 rings_enabled; + void *csr_addr; + struct qat_uio_bundle_dev uio_priv; + vm_object_t obj; +}; + +struct adf_uio_control_accel { + struct adf_accel_dev *accel_dev; + struct cdev *cdev; + struct mtx lock; + struct adf_bar *bar; + unsigned int nb_bundles; + unsigned int num_ker_bundles; + unsigned int total_used_bundles; + unsigned int num_handles; + struct cv cleanup_ok; + /* bundle[] must be last to allow dynamic size allocation. */ + struct adf_uio_control_bundle bundle[0]; + +}; + + +#endif /* end of include guard: QAT_UIO_CONTROL_H */ diff --git a/sys/dev/qat/qat/qat_ocf.c b/sys/dev/qat/qat/qat_ocf.c index 7e5025b0fa28..4960a5248c0c 100644 --- a/sys/dev/qat/qat/qat_ocf.c +++ b/sys/dev/qat/qat/qat_ocf.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Cryptodev headers */ #include @@ -44,6 +45,8 @@ MALLOC_DEFINE(M_QAT_OCF, "qat_ocf", "qat_ocf(4) memory allocations"); /* QAT OCF internal structures */ struct qat_ocf_softc { device_t sc_dev; + struct sysctl_oid *rc; + uint32_t enabled; int32_t cryptodev_id; struct qat_ocf_instance cyInstHandles[QAT_OCF_MAX_INSTANCES]; int32_t numCyInstances; @@ -560,17 +563,22 @@ qat_ocf_newsession(device_t dev, /* Create cryptodev session */ qat_softc = device_get_softc(dev); - qat_instance = - &qat_softc->cyInstHandles[cpu_id % qat_softc->numCyInstances]; - qat_dsession = crypto_get_driver_session(cses); - if (NULL == qat_dsession) { - device_printf(dev, "Unable to create new session\n"); - return (EINVAL); - } + if (qat_softc->numCyInstances > 0) { + qat_instance = + &qat_softc + ->cyInstHandles[cpu_id % qat_softc->numCyInstances]; + qat_dsession = crypto_get_driver_session(cses); + if (NULL == qat_dsession) { + device_printf(dev, "Unable to create new session\n"); + return (EINVAL); + } - /* Add only instance at this point remaining operations moved to - * lazy session init */ - qat_dsession->qatInstance = qat_instance; + /* Add only instance at this point remaining operations moved to + * lazy session init */ + qat_dsession->qatInstance = qat_instance; + } else { + return ENXIO; + } return 0; } @@ -988,6 +996,10 @@ qat_ocf_get_irq_instances(CpaInstanceHandle *cyInstHandles, if (NULL == baseAddr) continue; listTemp = baseAddr->sym_services; + if (NULL == listTemp) { + listTemp = baseAddr->crypto_services; + } + while (NULL != listTemp) { cyInstHandle = SalList_getObject(listTemp); status = cpaCyInstanceGetInfo2(cyInstHandle, &info); @@ -1023,8 +1035,6 @@ qat_ocf_start_instances(struct qat_ocf_softc *qat_softc, device_t dev) &numInstances); if (CPA_STATUS_SUCCESS != status) return status; - if (0 == numInstances) - return CPA_STATUS_RESOURCE; for (i = 0; i < numInstances; i++) { struct qat_ocf_instance *qat_ocf_instance; @@ -1041,11 +1051,18 @@ qat_ocf_start_instances(struct qat_ocf_softc *qat_softc, device_t dev) continue; } + qat_ocf_instance = &qat_softc->cyInstHandles[startedInstances]; + qat_ocf_instance->cyInstHandle = cyInstHandle; + mtx_init(&qat_ocf_instance->cyInstMtx, + "Instance MTX", + NULL, + MTX_DEF); + status = cpaCySetAddressTranslation(cyInstHandle, qatVirtToPhys); if (CPA_STATUS_SUCCESS != status) { device_printf(qat_softc->sc_dev, - "unable to add virt to phys callback"); + "unable to add virt to phys callback\n"); goto fail; } @@ -1056,13 +1073,6 @@ qat_ocf_start_instances(struct qat_ocf_softc *qat_softc, device_t dev) goto fail; } - qat_ocf_instance = &qat_softc->cyInstHandles[startedInstances]; - qat_ocf_instance->cyInstHandle = cyInstHandle; - mtx_init(&qat_ocf_instance->cyInstMtx, - "Instance MTX", - NULL, - MTX_DEF); - /* Initialize cookie pool */ status = qat_ocf_cookie_pool_init(qat_ocf_instance, dev); if (CPA_STATUS_SUCCESS != status) { @@ -1085,19 +1095,16 @@ qat_ocf_start_instances(struct qat_ocf_softc *qat_softc, device_t dev) startedInstances++; continue; fail: + mtx_destroy(&qat_ocf_instance->cyInstMtx); + /* Stop instance */ status = cpaCyStopInstance(cyInstHandle); if (CPA_STATUS_SUCCESS != status) device_printf(qat_softc->sc_dev, "unable to stop the instance\n"); - continue; } qat_softc->numCyInstances = startedInstances; - /* Success if at least one instance has been set */ - if (!qat_softc->numCyInstances) - return CPA_STATUS_FAIL; - return CPA_STATUS_SUCCESS; } @@ -1114,45 +1121,136 @@ qat_ocf_stop_instances(struct qat_ocf_softc *qat_softc) status = cpaCyStopInstance(qat_instance->cyInstHandle); if (CPA_STATUS_SUCCESS != status) { pr_err("QAT: stopping instance id: %d failed\n", i); - mtx_unlock(&qat_instance->cyInstMtx); continue; } qat_ocf_cookie_pool_deinit(qat_instance); mtx_destroy(&qat_instance->cyInstMtx); } + qat_softc->numCyInstances = 0; + return status; } +static int +qat_ocf_deinit(struct qat_ocf_softc *qat_softc) +{ + int status = 0; + CpaStatus cpaStatus; + + if (qat_softc->cryptodev_id >= 0) { + crypto_unregister_all(qat_softc->cryptodev_id); + qat_softc->cryptodev_id = -1; + } + + /* Stop QAT instances */ + cpaStatus = qat_ocf_stop_instances(qat_softc); + if (CPA_STATUS_SUCCESS != cpaStatus) { + device_printf(qat_softc->sc_dev, "unable to stop instances\n"); + status = EIO; + } + + return status; +} + +static int +qat_ocf_init(struct qat_ocf_softc *qat_softc) +{ + int32_t cryptodev_id; + + /* Starting instances for OCF */ + if (qat_ocf_start_instances(qat_softc, qat_softc->sc_dev)) { + device_printf(qat_softc->sc_dev, + "unable to get QAT IRQ instances\n"); + goto fail; + } + + /* Register only if instances available */ + if (qat_softc->numCyInstances) { + cryptodev_id = + crypto_get_driverid(qat_softc->sc_dev, + sizeof(struct qat_ocf_dsession), + CRYPTOCAP_F_HARDWARE); + if (cryptodev_id < 0) { + device_printf(qat_softc->sc_dev, + "cannot initialize!\n"); + goto fail; + } + qat_softc->cryptodev_id = cryptodev_id; + } + + return 0; +fail: + qat_ocf_deinit(qat_softc); + + return ENXIO; +} + +static int qat_ocf_sysctl_handle(SYSCTL_HANDLER_ARGS) +{ + struct qat_ocf_softc *qat_softc = NULL; + int ret = 0; + device_t dev = arg1; + u_int enabled; + + qat_softc = device_get_softc(dev); + enabled = qat_softc->enabled; + + ret = sysctl_handle_int(oidp, &enabled, 0, req); + if (ret || !req->newptr) + return (ret); + + if (qat_softc->enabled != enabled) { + if (enabled) { + ret = qat_ocf_init(qat_softc); + + } else { + ret = qat_ocf_deinit(qat_softc); + } + + if (!ret) + qat_softc->enabled = enabled; + } + + return ret; +} + static int qat_ocf_attach(device_t dev) { int status; struct qat_ocf_softc *qat_softc; - int32_t cryptodev_id; qat_softc = device_get_softc(dev); qat_softc->sc_dev = dev; + qat_softc->cryptodev_id = -1; + qat_softc->enabled = 1; - cryptodev_id = crypto_get_driverid(dev, - sizeof(struct qat_ocf_dsession), - CRYPTOCAP_F_HARDWARE); - if (cryptodev_id < 0) { - device_printf(dev, "cannot initialize!\n"); - goto fail; - } - qat_softc->cryptodev_id = cryptodev_id; + qat_softc->rc = + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, + "enable", + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, + dev, + 0, + qat_ocf_sysctl_handle, + "I", + "QAT OCF support enablement"); - /* Starting instances for OCF */ - status = qat_ocf_start_instances(qat_softc, dev); - if (status) { - device_printf(dev, "no QAT IRQ instances available\n"); - goto fail; + if (!qat_softc->rc) + return ENOMEM; + if (qat_softc->enabled) { + status = qat_ocf_init(qat_softc); + if (status) { + device_printf(dev, "qat_ocf init failed\n"); + goto fail; + } } return 0; fail: - qat_ocf_detach(dev); + qat_ocf_deinit(qat_softc); return (ENXIO); } @@ -1160,27 +1258,9 @@ qat_ocf_attach(device_t dev) static int qat_ocf_detach(device_t dev) { - struct qat_ocf_softc *qat_softc = NULL; - CpaStatus cpaStatus; - int status = 0; + struct qat_ocf_softc *qat_softc = device_get_softc(dev); - qat_softc = device_get_softc(dev); - - if (qat_softc->cryptodev_id >= 0) { - status = crypto_unregister_all(qat_softc->cryptodev_id); - if (status) - device_printf(dev, - "unable to unregister QAt backend\n"); - } - - /* Stop QAT instances */ - cpaStatus = qat_ocf_stop_instances(qat_softc); - if (CPA_STATUS_SUCCESS != cpaStatus) { - device_printf(dev, "unable to stop instances\n"); - status = EIO; - } - - return status; + return qat_ocf_deinit(qat_softc); } static device_method_t qat_ocf_methods[] = diff --git a/sys/dev/qat/qat_api/common/compression/dc_buffers.c b/sys/dev/qat/qat_api/common/compression/dc_buffers.c index 4f4e836ccf8f..efdc2de54197 100644 --- a/sys/dev/qat/qat_api/common/compression/dc_buffers.c +++ b/sys/dev/qat/qat_api/common/compression/dc_buffers.c @@ -172,3 +172,19 @@ cpaDcDeflateCompressBound(const CpaInstanceHandle dcInstance, return dcDeflateBoundGen2(huffType, inputSize, outputSize); } } + +CpaStatus +cpaDcLZ4CompressBound(const CpaInstanceHandle dcInstance, + Cpa32U inputSize, + Cpa32U *outputSize) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcLZ4SCompressBound(const CpaInstanceHandle dcInstance, + Cpa32U inputSize, + Cpa32U *outputSize) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_chain.c b/sys/dev/qat/qat_api/common/compression/dc_chain.c new file mode 100644 index 000000000000..6d7322720320 --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_chain.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_chain.c + * + * @ingroup Dc_Chaining + * + * @description + * Implementation of the chaining session operations. + * + *****************************************************************************/ + +/* + ******************************************************************************* + * Include public/global header files + ******************************************************************************* + */ +#include "cpa.h" + +#include "icp_qat_fw.h" +#include "icp_qat_fw_comp.h" +#include "icp_qat_hw.h" + +/* + ******************************************************************************* + * Include private header files + ******************************************************************************* + */ +#include "sal_types_compression.h" +#include "cpa_dc_chain.h" +#include "lac_session.h" +#include "dc_session.h" +#include "dc_datapath.h" +#include "dc_stats.h" +#include "lac_mem_pools.h" +#include "lac_log.h" +#include "sal_types_compression.h" +#include "lac_buffer_desc.h" +#include "sal_service_state.h" +#include "sal_qat_cmn_msg.h" +#include "lac_sym_qat_hash_defs_lookup.h" +#include "sal_string_parse.h" +#include "lac_sym.h" +#include "lac_session.h" +#include "lac_sym_qat.h" +#include "lac_sym_hash.h" +#include "lac_sym_alg_chain.h" +#include "lac_sym_auth_enc.h" + +CpaStatus +cpaDcChainGetSessionSize(CpaInstanceHandle dcInstance, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + Cpa32U *pSessionSize) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainInitSession(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + CpaDcCallbackFn callbackFn) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainRemoveSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainResetSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainPerformOp(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcChainOperations operation, + Cpa8U numOpDatas, + CpaDcChainOpData *pChainOpData, + CpaDcChainRqResults *pResults, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_datapath.c b/sys/dev/qat/qat_api/common/compression/dc_datapath.c index 526954e15227..880931e30ebb 100644 --- a/sys/dev/qat/qat_api/common/compression/dc_datapath.c +++ b/sys/dev/qat/qat_api/common/compression/dc_datapath.c @@ -331,6 +331,12 @@ dcCompression_ProcessCallback(void *pRespMsg) (ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_SET == ICP_QAT_FW_COMN_RESP_CMP_END_OF_LAST_BLK_FLAG_GET( opStatus)); + } else { + /* Check if returned data is a stored block + * in compression direction + */ + pResults->dataUncompressed = + ICP_QAT_FW_COMN_HDR_ST_BLK_FLAG_GET(hdrFlags); } /* Save the checksum for the next request */ diff --git a/sys/dev/qat/qat_api/common/compression/dc_dp.c b/sys/dev/qat/qat_api/common/compression/dc_dp.c index 9b00c5b09d7e..b9d3d17a8548 100644 --- a/sys/dev/qat/qat_api/common/compression/dc_dp.c +++ b/sys/dev/qat/qat_api/common/compression/dc_dp.c @@ -273,6 +273,14 @@ cpaDcDpRemoveSession(const CpaInstanceHandle dcInstance, return cpaDcRemoveSession(dcInstance, pSessionHandle); } +CpaStatus +cpaDcDpUpdateSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pUpdateSessionData) +{ + return CPA_STATUS_UNSUPPORTED; +} + CpaStatus cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance, const CpaDcDpCallbackFn pNewCb) diff --git a/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c b/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c new file mode 100644 index 000000000000..24602282dc5e --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_ns_datapath.c + * + * @defgroup Dc_DataCompression DC Data Compression + * + * @ingroup Dc_DataCompression + * + * @description + * Implementation of the Data Compression datapath operations. + * + *****************************************************************************/ + +/* +******************************************************************************* +* Include public/global header files +******************************************************************************* +*/ +#include "cpa.h" +#include "cpa_dc.h" +#include "cpa_dc_dp.h" + +/* +******************************************************************************* +* Include private header files +******************************************************************************* +*/ +#include "dc_session.h" +#include "dc_datapath.h" +#include "sal_statistics.h" +#include "lac_common.h" +#include "lac_mem.h" +#include "lac_mem_pools.h" +#include "lac_log.h" +#include "sal_types_compression.h" +#include "dc_stats.h" +#include "lac_buffer_desc.h" +#include "lac_sal.h" +#include "lac_sync.h" +#include "sal_service_state.h" +#include "sal_qat_cmn_msg.h" +#include "dc_error_counter.h" + +CpaStatus +cpaDcNsDecompressData(CpaInstanceHandle dcInstance, + CpaDcNsSetupData *pSetupData, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcOpData *pOpData, + CpaDcRqResults *pResults, + CpaDcCallbackFn callbackFn, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcNsCompressData(CpaInstanceHandle dcInstance, + CpaDcNsSetupData *pSetupData, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcOpData *pOpData, + CpaDcRqResults *pResults, + CpaDcCallbackFn callbackFn, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c b/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c new file mode 100644 index 000000000000..a4031c0bd513 --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_ns_header_footer.c + * + * @ingroup Dc_DataCompression + * + * @description + * Implementation of the Data Compression header and footer operations. + * + *****************************************************************************/ + +/* + ******************************************************************************* + * Include public/global header files + ******************************************************************************* + */ +#include "cpa.h" +#include "cpa_dc.h" + +/* + ******************************************************************************* + * Include private header files + ******************************************************************************* + */ +#include "dc_session.h" + +CpaStatus +cpaDcNsGenerateHeader(CpaDcNsSetupData *pSetupData, + CpaFlatBuffer *pDestBuff, + Cpa32U *count) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcNsGenerateFooter(CpaDcNsSetupData *pSetupData, + Cpa64U totalLength, + CpaFlatBuffer *pDestBuff, + CpaDcRqResults *pResults) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_session.c b/sys/dev/qat/qat_api/common/compression/dc_session.c index fbce72cb7bfb..ab433adc18fd 100644 --- a/sys/dev/qat/qat_api/common/compression/dc_session.c +++ b/sys/dev/qat/qat_api/common/compression/dc_session.c @@ -65,14 +65,13 @@ dcCheckSessionData(const CpaDcSessionSetupData *pSessionData, cpaDcQueryCapabilities(dcInstance, &instanceCapabilities); if ((pSessionData->compLevel < CPA_DC_L1) || - (pSessionData->compLevel > CPA_DC_L9)) { + (pSessionData->compLevel > CPA_DC_L12)) { QAT_UTILS_LOG("Invalid compLevel value\n"); return CPA_STATUS_INVALID_PARAM; } if ((pSessionData->autoSelectBestHuffmanTree < CPA_DC_ASB_DISABLED) || - (pSessionData->autoSelectBestHuffmanTree > - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS)) { + (pSessionData->autoSelectBestHuffmanTree > CPA_DC_ASB_ENABLED)) { QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n"); return CPA_STATUS_INVALID_PARAM; } @@ -869,6 +868,13 @@ dcInitSession(CpaInstanceHandle dcInstance, disableType0EnhancedAutoSelectBest = ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST; break; + case CPA_DC_ASB_ENABLED: + if (pService->comp_device_data.asbEnableSupport == CPA_FALSE) { + autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST; + enhancedAutoSelectBest = + ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST; + } + break; default: break; } @@ -1088,6 +1094,21 @@ cpaDcResetSession(const CpaInstanceHandle dcInstance, return status; } +CpaStatus +cpaDcResetXXHashState(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcUpdateSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pUpdateSessionData) +{ + return CPA_STATUS_UNSUPPORTED; +} + CpaStatus cpaDcRemoveSession(const CpaInstanceHandle dcInstance, CpaDcSessionHandle pSessionHandle) diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_session.h b/sys/dev/qat/qat_api/common/compression/include/dc_session.h index 041c60e5845c..108159f1190c 100644 --- a/sys/dev/qat/qat_api/common/compression/include/dc_session.h +++ b/sys/dev/qat/qat_api/common/compression/include/dc_session.h @@ -208,8 +208,6 @@ typedef struct dc_session_desc_s { /**< Session direction */ CpaDcSessionState sessState; /**< Session state */ - Cpa32U deflateWindowSize; - /**< Window size */ CpaDcCompLvl compLevel; /**< Compression level */ CpaDcCallbackFn pCompressionCb; diff --git a/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c b/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c index 604e5751fba9..cab8d6c7796c 100644 --- a/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c +++ b/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c @@ -2449,20 +2449,12 @@ LacSymKey_KeyGenSslTls(const CpaInstanceHandle instanceHandle_in, { CpaStatus status = CPA_STATUS_FAIL; CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in); - CpaCyCapabilitiesInfo cyCapInfo; LAC_CHECK_INSTANCE_HANDLE(instanceHandle); SAL_CHECK_INSTANCE_TYPE(instanceHandle, (SAL_SERVICE_TYPE_CRYPTO | SAL_SERVICE_TYPE_CRYPTO_SYM)); - SAL_RUNNING_CHECK(instanceHandle); - SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo); - - if (IS_HKDF_UNSUPPORTED(cmdId, cyCapInfo.hkdfSupported)) { - LAC_LOG_ERROR("The device does not support HKDF"); - return CPA_STATUS_UNSUPPORTED; - } status = LacSymKey_CheckParamSslTls(pKeyGenOpData, hashAlgorithm, diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c index 9234b649cf2f..5b4ebdc85654 100644 --- a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c +++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c @@ -1147,8 +1147,8 @@ LacAlgChain_SessionInit(const CpaInstanceHandle instanceHandle, * build the message templates * create two content descriptors in the case we can support using SHRAM * constants and an optimised content descriptor. we have to do this in - *case of partials. 64 byte content descriptor is used in the SHRAM case - *for AES-128-HMAC-SHA1 + * case of partials. 64 byte content descriptor is used in the SHRAM + * case for AES-128-HMAC-SHA1 *-----------------------------------------------------------------------*/ if (CPA_STATUS_SUCCESS == status) { pSessionDesc->cipherSliceType = diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_compression.c b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c index 9827015767bf..1a59d81da53b 100644 --- a/sys/dev/qat/qat_api/common/ctrl/sal_compression.c +++ b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c @@ -126,7 +126,7 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, sal_compression_service_t *pCompService) { int level = 0; - + pCompService->comp_device_data.asbEnableSupport = CPA_FALSE; pCompService->comp_device_data.uniqueCompressionLevels[0] = CPA_FALSE; switch (device->deviceType) { @@ -154,6 +154,23 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, pCompService->comp_device_data.windowSizeMask = (1 << DC_8K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); pCompService->comp_device_data.cnvnrSupported = CPA_FALSE; + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; case DEVICE_C3XXX: case DEVICE_C3XXXVF: @@ -181,6 +198,24 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED; pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; + + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; case DEVICE_C62X: case DEVICE_C62XVF: @@ -209,7 +244,7 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED; pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; - for (level = CPA_DC_L1; level <= CPA_DC_L9; level++) { + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { switch (level) { case CPA_DC_L1: case CPA_DC_L2: @@ -254,8 +289,28 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, pCompService->comp_device_data.windowSizeMask = (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; + + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + case CPA_DC_L5: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; - case DEVICE_GEN4: + case DEVICE_4XXX: + case DEVICE_4XXXVF: pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE; pCompService->numInterBuffs = 0; pCompService->comp_device_data.minOutputBuffSize = @@ -277,7 +332,7 @@ SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device, pCompService->comp_device_data.windowSizeMask = (1 << DC_4K_WINDOW_SIZE | 1 << DC_8K_WINDOW_SIZE | 1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); - for (level = CPA_DC_L1; level <= CPA_DC_L9; level++) { + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { switch (level) { case CPA_DC_L1: case CPA_DC_L6: diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c b/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c index 10ce54c0ce43..d0a92081b532 100644 --- a/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c +++ b/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c @@ -478,7 +478,8 @@ selectGeneration(device_type_t deviceType, sal_service_t *pInst) pInst->gen = GEN3; break; - case DEVICE_GEN4: + case DEVICE_4XXX: + case DEVICE_4XXXVF: pInst->gen = GEN4; break; @@ -719,6 +720,28 @@ SalCtrl_ServiceStop(icp_accel_dev_t *device, sal_list_t *services) return status; } +static CpaStatus +SalCtrl_ServiceError(icp_accel_dev_t *device, sal_list_t *services) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + + /* Calling error handling functions */ + sal_list_t *curr_element = services; + sal_service_t *service = NULL; + while (NULL != curr_element) { + service = (sal_service_t *)SalList_getObject(curr_element); + if (service->notification_cb) { + service->notification_cb( + service, + service->cb_tag, + CPA_INSTANCE_EVENT_FATAL_ERROR); + } + curr_element = SalList_next(curr_element); + } + + return status; +} + /* * @ingroup SalCtrl * @description @@ -1164,6 +1187,78 @@ SalCtrl_ServiceEventStop(icp_accel_dev_t *device, Cpa32U enabled_services) return ret_status; } +/************************************************************************** + * @ingroup SalCtrl + * @description + * This function calls the error function on all the service instances. + * + * @context + * This function is called from the SalCtrl_ServiceEventHandler function. + * + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] device An icp_accel_dev_t* type + * @param[in] enabled_services Enabled services by user + * + **************************************************************************/ +static CpaStatus +SalCtrl_ServiceEventError(icp_accel_dev_t *device, Cpa32U enabled_services) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + CpaStatus ret_status = CPA_STATUS_SUCCESS; + sal_t *service_container = device->pSalHandle; + + if (service_container == NULL) { + QAT_UTILS_LOG("Private data is NULL\n"); + return CPA_STATUS_FATAL; + } + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO_ASYM)) { + status = SalCtrl_ServiceError(device, + service_container->asym_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO_SYM)) { + status = SalCtrl_ServiceError(device, + service_container->sym_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO)) { + status = + SalCtrl_ServiceError(device, + service_container->crypto_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_COMPRESSION)) { + status = SalCtrl_ServiceError( + device, service_container->compression_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + return ret_status; +} + /************************************************************************** * @ingroup SalCtrl * @description @@ -1307,6 +1402,10 @@ SalCtrl_ServiceEventHandler(icp_accel_dev_t *device, } break; } + case ICP_ADF_EVENT_ERROR: { + status = SalCtrl_ServiceEventError(device, enabled_services); + break; + } default: status = CPA_STATUS_SUCCESS; break; diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c b/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c new file mode 100644 index 000000000000..1857d58c6907 --- /dev/null +++ b/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file sal_get_instances.c + * + * @defgroup SalCtrl Service Access Layer Controller + * + * @ingroup SalCtrl + * + * @description + * This file contains the main function to get SAL instances. + * + *****************************************************************************/ + +/* +******************************************************************************* +* Include public/global header files +******************************************************************************* +*/ + +/* QAT-API includes */ +#include "cpa.h" +#include "cpa_cy_common.h" +#include "cpa_cy_im.h" +#include "cpa_dc.h" + +/* ADF includes */ +#include "icp_accel_devices.h" +#include "icp_adf_accel_mgr.h" + +/* SAL includes */ +#include "lac_mem.h" +#include "lac_list.h" +#include "lac_sal_types.h" + +/** + ****************************************************************************** + * @ingroup SalCtrl + * @description + * Get either sym or asym instance number + *****************************************************************************/ +static CpaStatus +Lac_GetSingleCyNumInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + icp_accel_dev_t **pAdfInsts = NULL; + icp_accel_dev_t *dev_addr = NULL; + sal_t *base_addr = NULL; + sal_list_t *list_temp = NULL; + Cpa16U num_accel_dev = 0; + Cpa16U num_inst = 0; + Cpa16U i = 0; + Cpa32U accel_capability = 0; + char *service = NULL; + + LAC_CHECK_NULL_PARAM(pNumInstances); + *pNumInstances = 0; + + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + service = "asym"; + break; + + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + service = "sym"; + break; + + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } + + /* Get the number of accel_dev in the system */ + status = icp_amgr_getNumInstances(&num_accel_dev); + LAC_CHECK_STATUS(status); + + /* Allocate memory to store addr of accel_devs */ + pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), + M_QAT, + M_WAITOK | M_ZERO); + if (NULL == pAdfInsts) { + QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); + return CPA_STATUS_RESOURCE; + } + + num_accel_dev = 0; + status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, + pAdfInsts, + &num_accel_dev); + if (CPA_STATUS_SUCCESS != status) { + QAT_UTILS_LOG("No support for service %s\n", service); + free(pAdfInsts, M_QAT); + return status; + } + + for (i = 0; i < num_accel_dev; i++) { + dev_addr = pAdfInsts[i]; + if (NULL == dev_addr || NULL == dev_addr->pSalHandle) { + continue; + } + base_addr = dev_addr->pSalHandle; + + if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) { + list_temp = base_addr->asym_services; + } else { + list_temp = base_addr->sym_services; + } + while (NULL != list_temp) { + num_inst++; + list_temp = SalList_next(list_temp); + } + } + + *pNumInstances = num_inst; + free(pAdfInsts, M_QAT); + + return status; +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + * @description + * Get either sym or asym instance + *****************************************************************************/ +static CpaStatus +Lac_GetSingleCyInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *pInstances) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + icp_accel_dev_t **pAdfInsts = NULL; + icp_accel_dev_t *dev_addr = NULL; + sal_t *base_addr = NULL; + sal_list_t *list_temp = NULL; + Cpa16U num_accel_dev = 0; + Cpa16U num_allocated_instances = 0; + Cpa16U index = 0; + Cpa16U i = 0; + Cpa32U accel_capability = 0; + char *service = NULL; + + LAC_CHECK_NULL_PARAM(pInstances); + if (0 == numInstances) { + QAT_UTILS_LOG("NumInstances is 0\n"); + return CPA_STATUS_INVALID_PARAM; + } + + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + service = "asym"; + break; + + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + service = "sym"; + break; + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } + + /* Get the number of instances */ + status = cpaGetNumInstances(accelerationServiceType, + &num_allocated_instances); + if (CPA_STATUS_SUCCESS != status) { + return status; + } + + if (numInstances > num_allocated_instances) { + QAT_UTILS_LOG("Only %d instances available\n", + num_allocated_instances); + return CPA_STATUS_RESOURCE; + } + + /* Get the number of accel devices in the system */ + status = icp_amgr_getNumInstances(&num_accel_dev); + LAC_CHECK_STATUS(status); + + /* Allocate memory to store addr of accel_devs */ + pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), + M_QAT, + M_WAITOK | M_ZERO); + if (NULL == pAdfInsts) { + QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); + return CPA_STATUS_RESOURCE; + } + + num_accel_dev = 0; + status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, + pAdfInsts, + &num_accel_dev); + if (CPA_STATUS_SUCCESS != status) { + QAT_UTILS_LOG("No support for service %s\n", service); + free(pAdfInsts, M_QAT); + return status; + } + + for (i = 0; i < num_accel_dev; i++) { + dev_addr = pAdfInsts[i]; + /* Note dev_addr cannot be NULL here as numInstances = 0 + * is not valid and if dev_addr = NULL then index = 0 (which + * is less than numInstances and status is set to _RESOURCE + * above) + */ + base_addr = dev_addr->pSalHandle; + if (NULL == base_addr) { + continue; + } + + if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) + list_temp = base_addr->asym_services; + else + list_temp = base_addr->sym_services; + while (NULL != list_temp) { + if (index > (numInstances - 1)) + break; + + pInstances[index] = SalList_getObject(list_temp); + list_temp = SalList_next(list_temp); + index++; + } + } + free(pAdfInsts, M_QAT); + + return status; +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + *****************************************************************************/ +CpaStatus +cpaGetNumInstances(const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances) +{ + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + return Lac_GetSingleCyNumInstances(accelerationServiceType, + pNumInstances); + case CPA_ACC_SVC_TYPE_CRYPTO: + return cpaCyGetNumInstances(pNumInstances); + case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: + return cpaDcGetNumInstances(pNumInstances); + + default: + QAT_UTILS_LOG("Invalid service type\n"); + *pNumInstances = 0; + return CPA_STATUS_INVALID_PARAM; + } +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + *****************************************************************************/ +CpaStatus +cpaGetInstances(const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *pInstances) +{ + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + return Lac_GetSingleCyInstances(accelerationServiceType, + numInstances, + pInstances); + + case CPA_ACC_SVC_TYPE_CRYPTO: + return cpaCyGetInstances(numInstances, pInstances); + case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: + return cpaDcGetInstances(numInstances, pInstances); + + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } +} diff --git a/sys/dev/qat/qat_api/common/include/sal_types_compression.h b/sys/dev/qat/qat_api/common/include/sal_types_compression.h index 80e3c89ea699..2851a82b730b 100644 --- a/sys/dev/qat/qat_api/common/include/sal_types_compression.h +++ b/sys/dev/qat/qat_api/common/include/sal_types_compression.h @@ -23,7 +23,7 @@ #include "icp_adf_transport.h" #define DC_NUM_RX_RINGS (1) -#define DC_NUM_COMPRESSION_LEVELS (CPA_DC_L9) +#define DC_NUM_COMPRESSION_LEVELS (CPA_DC_L12) /** ***************************************************************************** @@ -73,6 +73,9 @@ typedef struct sal_compression_device_data { /* Flag to indicate CompressAndVerifyAndRecover feature support */ CpaBoolean cnvnrSupported; + + /* When set, implies device supports ASB_ENABLE */ + CpaBoolean asbEnableSupport; } sal_compression_device_data_t; /** diff --git a/sys/dev/qat/qat_api/common/stubs/lac_stubs.c b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c index b9c0c3237a6c..f6c90e5e79d6 100644 --- a/sys/dev/qat/qat_api/common/stubs/lac_stubs.c +++ b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c @@ -29,6 +29,9 @@ #include "cpa_cy_rsa.h" #include "cpa_cy_ln.h" #include "cpa_dc.h" +#include "cpa_dc_chain.h" +#include "cpa_cy_ecsm2.h" +#include "cpa_cy_kpt.h" #include "icp_accel_devices.h" #include "icp_adf_init.h" #include "icp_adf_transport.h" @@ -283,6 +286,194 @@ cpaCyEcMontEdwdsPointMultiply( return CPA_STATUS_UNSUPPORTED; } +CpaStatus +cpaCyEcGenericPointVerify(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointVerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcGenericPointVerifyOpData *pOpData, + CpaBoolean *pVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcGenericPointMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcGenericPointMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pOutX, + CpaFlatBuffer *pOutY) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2PointMultiply( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointMultiplyCbFunc pEcsm2PointMulCb, + void *pCallbackTag, + const CpaCyEcsm2PointMultiplyOpData *pEcsm2PointMulOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2GeneratorMultiply( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointMultiplyCbFunc pEcsm2GenMulCb, + void *pCallbackTag, + const CpaCyEcsm2GeneratorMultiplyOpData *pEcsm2GenMulOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2PointVerify( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointVerifyCbFunc pEcsm2PointVeirfyCb, + void *pCallbackTag, + const CpaCyEcsm2PointVerifyOpData *pEcsm2PointVerifyOpData, + CpaBoolean *pPointVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Sign(const CpaInstanceHandle instanceHandle_in, + const CpaCyEcsm2SignCbFunc pEcsm2SignCb, + void *pCallbackTag, + const CpaCyEcsm2SignOpData *pEcsm2SignOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Verify(const CpaInstanceHandle instanceHandle_in, + const CpaCyEcsm2VerifyCbFunc pEcsm2VerifyCb, + void *pCallbackTag, + const CpaCyEcsm2VerifyOpData *pEcsm2VerifyOpData, + CpaBoolean *pVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Encrypt(const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2EncCb, + void *pCallbackTag, + const CpaCyEcsm2EncryptOpData *pEcsm2EncOpData, + CpaCyEcsm2EncryptOutputData *pEcsm2EncOutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Decrypt(const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2DecCb, + void *pCallbackTag, + const CpaCyEcsm2DecryptOpData *pEcsm2DecOpData, + CpaCyEcsm2DecryptOutputData *pEcsm2DecOutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2KeyExPhase1( + const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2KeyExPhase1Cb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase1OpData *pEcsm2KeyExPhase1OpData, + CpaCyEcsm2KeyExOutputData *pEcsm2KeyExPhase1OutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2KeyExPhase2( + const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2KeyExPhase2Cb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase2OpData *pEcsm2KeyExPhase2OpData, + CpaCyEcsm2KeyExOutputData *pEcsm2KeyExPhase2OutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2QueryStats64(const CpaInstanceHandle instanceHandle_in, + CpaCyEcsm2Stats64 *pEcsm2Stats) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptEcdsaSignRS(const CpaInstanceHandle instanceHandle, + const CpaCyEcdsaSignRSCbFunc pCb, + void *pCallbackTag, + const CpaCyKptEcdsaSignRSOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS, + CpaCyKptUnwrapContext *pKptUnwrapContext) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptRsaDecrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pRsaDecryptCb, + void *pCallbackTag, + const CpaCyKptRsaDecryptOpData *pDecryptOpData, + CpaFlatBuffer *pOutputData, + CpaCyKptUnwrapContext *pKptUnwrapContext) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptQueryIssuingKeys(const CpaInstanceHandle instanceHandle_in, + CpaFlatBuffer *pPublicX509IssueCert, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptQueryDeviceCredentials(const CpaInstanceHandle instanceHandle, + CpaCyKptValidationKey *pDevCredential, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptLoadKey(CpaInstanceHandle instanceHandle, + CpaCyKptLoadKey *pSWK, + CpaCyKptHandle *keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptDeleteKey(CpaInstanceHandle instanceHandle, + CpaCyKptHandle keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + /* Prime */ CpaStatus cpaCyPrimeTest(const CpaInstanceHandle instanceHandle, diff --git a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h index 855e83905f5c..6893cbedb594 100644 --- a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h +++ b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ + +/* --- (Automatically generated (build v. 2.7), do not modify manually) --- */ + + /** * @file icp_qat_fw_mmp.h * @defgroup icp_qat_fw_mmp ICP QAT FW MMP Processing Definitions @@ -12,5915 +16,7233 @@ * accelerate crypto assymetric applications */ + #ifndef __ICP_QAT_FW_MMP__ #define __ICP_QAT_FW_MMP__ + /************************************************************************** * Include local header files ************************************************************************** */ + #include "icp_qat_fw.h" + /************************************************************************** * Local constants ************************************************************************** */ -#define ICP_QAT_FW_PKE_INPUT_COUNT_MAX 7 +#define ICP_QAT_FW_PKE_INPUT_COUNT_MAX 7 /**< @ingroup icp_qat_fw_pke * Maximum number of input paramaters in all PKE request */ -#define ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX 5 +#define ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX 5 /**< @ingroup icp_qat_fw_pke * Maximum number of output paramaters in all PKE request */ +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p384_input_s +{ + uint64_t xp; /**< xP = affine coordinate X of point P (6 qwords)*/ + uint64_t yp; /**< yP = affine coordinate Y of point P (6 qwords)*/ + uint64_t k; /**< k = scalar (6 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p384_input_s +{ + uint64_t k; /**< k = scalar (6 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s +{ + uint64_t k; /**< k = random value, > 0 and < n (order of G for P384) + (6 qwords)*/ + uint64_t e; /**< (6 qwords)*/ + uint64_t d; /**< (6 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p256_input_s +{ + uint64_t xp; /**< xP = affine coordinate X of point P (4 qwords)*/ + uint64_t yp; /**< yP = affine coordinate Y of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p256_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s +{ + uint64_t k; /**< k = random value, > 0 and < n (order of G for P256) + (4 qwords)*/ + uint64_t e; /**< (4 qwords)*/ + uint64_t d; /**< (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC SM2 point multiply [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECSM2_GENERATOR_MULTIPLICATION. + */ +typedef struct icp_qat_fw_mmp_ecsm2_generator_multiplication_input_s +{ + uint64_t k; /**< k = multiplicand (4 qwords)*/ +} icp_qat_fw_mmp_ecsm2_generator_multiplication_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Initialisation sequence , * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_INIT. */ -typedef struct icp_qat_fw_mmp_init_input_s { - uint64_t z; /**< zeroed quadword (1 qwords)*/ +typedef struct icp_qat_fw_mmp_init_input_s +{ + uint64_t z; /**< zeroed quadword (1 qwords)*/ } icp_qat_fw_mmp_init_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_768. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_768. */ -typedef struct icp_qat_fw_mmp_dh_g2_768_input_s { - uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ - uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_768_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ + uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_dh_g2_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for 768-bit - * numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_768. + * Input parameter list for Diffie-Hellman Modular exponentiation for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_768. */ -typedef struct icp_qat_fw_mmp_dh_768_input_s { - uint64_t g; /**< base ≥ 0 and < 2^768 (12 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ - uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_768_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^768 (12 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ + uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_dh_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_1024. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_1024. */ -typedef struct icp_qat_fw_mmp_dh_g2_1024_input_s { - uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1024_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_dh_g2_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_1024. + * Input parameter list for Diffie-Hellman Modular exponentiation for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_1024. */ -typedef struct icp_qat_fw_mmp_dh_1024_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1024_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_dh_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_1536. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_1536. */ -typedef struct icp_qat_fw_mmp_dh_g2_1536_input_s { - uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1536_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_dh_g2_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_1536. + * Input parameter list for Diffie-Hellman Modular exponentiation for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_1536. */ -typedef struct icp_qat_fw_mmp_dh_1536_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1536_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_dh_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_2048. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_2048. */ -typedef struct icp_qat_fw_mmp_dh_g2_2048_input_s { - uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_2048_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_dh_g2_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_2048. + * Input parameter list for Diffie-Hellman Modular exponentiation for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_2048. */ -typedef struct icp_qat_fw_mmp_dh_2048_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_2048_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_dh_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_3072. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_3072. */ -typedef struct icp_qat_fw_mmp_dh_g2_3072_input_s { - uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_3072_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_dh_g2_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_3072. + * Input parameter list for Diffie-Hellman Modular exponentiation for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_3072. */ -typedef struct icp_qat_fw_mmp_dh_3072_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_3072_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_dh_3072_input_t; -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_4096. - */ -typedef struct icp_qat_fw_mmp_dh_g2_4096_input_s { - uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_dh_g2_4096_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_4096. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_4096. */ -typedef struct icp_qat_fw_mmp_dh_4096_input_s { - uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_4096_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_dh_g2_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Diffie-Hellman Modular exponentiation for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_4096. + */ +typedef struct icp_qat_fw_mmp_dh_4096_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_dh_4096_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for RSA 512 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_512. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers , to be used when icp_qat_fw_pke_request_s::functionalityId + * is #PKE_DH_G2_8192. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_512_input_s { - uint64_t - p; /**< RSA parameter, prime,  2 < p < 2^256 (4 qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2 < q < 2^256 (4 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_8192_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus ≥ 2^8191 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_dh_g2_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Diffie-Hellman Modular exponentiation for + * 8192-bit numbers , to be used when icp_qat_fw_pke_request_s::functionalityId + * is #PKE_DH_8192. + */ +typedef struct icp_qat_fw_mmp_dh_8192_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus ≥ 2^8191 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_dh_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 512 key generation first form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_512. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_512_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^256 (4 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_512. */ -typedef struct icp_qat_fw_mmp_rsa_kp2_512_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp2_512_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_512. */ -typedef struct icp_qat_fw_mmp_rsa_ep_512_input_s { - uint64_t m; /**< message representative, < n (8 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (8 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^256 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_512_input_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (8 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^256 (8 qwords)*/ } icp_qat_fw_mmp_rsa_ep_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_512_input_s { - uint64_t c; /**< cipher text representative, < n (8 qwords)*/ - uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^256 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_512_input_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ + uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^256 (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_512_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (4 qwords)*/ - uint64_t dq; /**< RSA private key 0 < dq < q-1 (4 qwords)*/ - uint64_t qinv; /**< RSA private key 0 < qInv < p (4 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_512_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (4 qwords)*/ + uint64_t dq; /**< RSA private key 0 < dq < q-1 (4 qwords)*/ + uint64_t qinv; /**< RSA private key 0 < qInv < p (4 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1024_input_s { - uint64_t - p; /**< RSA parameter, prime,  2 < p < 2^512 (8 qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2 < q < 2^512 (8 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_1024_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^512 (8 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_1024. */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1024_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp2_1024_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_1024. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1024_input_s { - uint64_t m; /**< message representative, < n (16 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (16 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1024_input_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (16 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1024_input_s { - uint64_t c; /**< cipher text representative, < n (16 qwords)*/ - uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1024_input_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ + uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1024_input_t; + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1024 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1024_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (8 qwords)*/ + uint64_t dq; /**< RSA private key 0 < dq < q-1 (8 qwords)*/ + uint64_t qinv; /**< RSA private key 0 < qInv < p (8 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1536 key generation first form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_1536_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^768 (12 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1536 key generation second form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1536_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^767 < q < 2^768 (12 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1536 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_1536_input_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ (p*q)-1 (24 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^1536 (24 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1536 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_1536_input_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^1536 (24 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 1536 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1536_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (12 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (12 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (12 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 2048 key generation first form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_2048_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1024 (16 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 2048 key generation second form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_2048_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 (16 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 2048 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_2048_input_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (32 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 2048 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_2048_input_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 2048 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_2048_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 (16 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (16 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (16 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (16 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 3072 key generation first form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_3072_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1536 (24 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 3072 key generation second form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_3072_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 (24 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 3072 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_3072_input_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (48 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 3072 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_3072_input_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 3072 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_3072_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 (24 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (24 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (24 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (24 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 4096 key generation first form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_4096_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^2048 (32 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 4096 key generation second form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_4096_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 (32 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 4096 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_4096_input_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (64 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 4096 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_4096_input_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 4096 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_4096_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 (32 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (32 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (32 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (32 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_4096_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 8192 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_RSA_EP_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_8192_input_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (128 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_8192_input_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ + uint64_t d; /**< RSA private key (128 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 8192 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_RSA_DP2_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_8192_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (128 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^4095 < p < 2^4096 (64 + qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^4095 < q < 2^4096 (64 + qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (64 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (64 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (64 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 192-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_192. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_192_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^192 (3 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_192_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 256-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_256. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_256_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^256 (4 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 384-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_384. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_384_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^384 (6 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_384_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_512. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_512_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_768. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_768_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^768 (12 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_1024. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_1024_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^1024 (16 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_1536. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_1536_input_s +{ + uint64_t m; /**< (24 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_2048. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_2048_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_3072. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_3072_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_4096. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_4096_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_gcd_pt_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_160. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_160_input_s +{ + uint64_t m; /**< prime candidate, 2^159 < m < 2^160 (3 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_512. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_512_input_s +{ + uint64_t m; /**< prime candidate, 2^511 < m < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for <e; 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_L512. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_l512_input_s +{ + uint64_t m; /**< prime candidate, 5 < m < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_768. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_768_input_s +{ + uint64_t m; /**< prime candidate, 2^767 < m < 2^768 (12 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_1024. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_1024_input_s +{ + uint64_t m; /**< prime candidate, 2^1023 < m < 2^1024 (16 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_1536. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_1536_input_s +{ + uint64_t m; /**< prime candidate, 2^1535 < m < 2^1536 (24 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_2048. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_2048_input_s +{ + uint64_t m; /**< prime candidate, 2^2047 < m < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_3072. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_3072_input_s +{ + uint64_t m; /**< prime candidate, 2^3071 < m < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Fermat primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_4096. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_4096_input_s +{ + uint64_t m; /**< prime candidate, 2^4095 < m < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_fermat_pt_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_160. + */ +typedef struct icp_qat_fw_mmp_mr_pt_160_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (3 qwords)*/ + uint64_t m; /**< prime candidate > 2^159 and < 2^160 (3 qwords)*/ +} icp_qat_fw_mmp_mr_pt_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_512. + */ +typedef struct icp_qat_fw_mmp_mr_pt_512_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ + uint64_t m; /**< prime candidate > 2^511 and < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_mr_pt_512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_768. + */ +typedef struct icp_qat_fw_mmp_mr_pt_768_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (12 qwords)*/ + uint64_t m; /**< prime candidate > 2^767 and < 2^768 (12 qwords)*/ +} icp_qat_fw_mmp_mr_pt_768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_1024. + */ +typedef struct icp_qat_fw_mmp_mr_pt_1024_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (16 qwords)*/ + uint64_t m; /**< prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ +} icp_qat_fw_mmp_mr_pt_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_1536. + */ +typedef struct icp_qat_fw_mmp_mr_pt_1536_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (24 qwords)*/ + uint64_t m; /**< prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ +} icp_qat_fw_mmp_mr_pt_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_2048. + */ +typedef struct icp_qat_fw_mmp_mr_pt_2048_input_s +{ + uint64_t x; /**< randomness > 1 and <m-1 (32 qwords)*/ + uint64_t m; /**< prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_mr_pt_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_3072. + */ +typedef struct icp_qat_fw_mmp_mr_pt_3072_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (48 qwords)*/ + uint64_t m; /**< prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_mr_pt_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_4096. + */ +typedef struct icp_qat_fw_mmp_mr_pt_4096_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (64 qwords)*/ + uint64_t m; /**< prime candidate > 2^4095 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_mr_pt_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_L512. + */ +typedef struct icp_qat_fw_mmp_mr_pt_l512_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ + uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_mr_pt_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_160. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_160_input_s +{ + uint64_t m; /**< odd prime candidate > 2^159 and < 2^160 (3 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_512. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_512_input_s +{ + uint64_t m; /**< odd prime candidate > 2^511 and < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_768. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_768_input_s +{ + uint64_t m; /**< odd prime candidate > 2^767 and < 2^768 (12 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_1024. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_1024_input_s +{ + uint64_t m; /**< odd prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_1536. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_1536_input_s +{ + uint64_t m; /**< odd prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_2048. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_2048_input_s +{ + uint64_t m; /**< odd prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_3072. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_3072_input_s +{ + uint64_t m; /**< odd prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_4096. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_4096_input_s +{ + uint64_t m; /**< odd prime candidate > 2^4096 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_4096_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Lucas primality test for L512-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_L512. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_l512_input_s +{ + uint64_t m; /**< odd prime candidate > 5 and < 2^512 (8 qwords)*/ +} icp_qat_fw_mmp_lucas_pt_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 512-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L512. + */ +typedef struct icp_qat_fw_maths_modexp_l512_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^512 (8 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^512 (8 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^512 (8 qwords)*/ +} icp_qat_fw_maths_modexp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 1024-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L1024. + */ +typedef struct icp_qat_fw_maths_modexp_l1024_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^1024 (16 qwords)*/ +} icp_qat_fw_maths_modexp_l1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 1536-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L1536. + */ +typedef struct icp_qat_fw_maths_modexp_l1536_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^1536 (24 qwords)*/ +} icp_qat_fw_maths_modexp_l1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 2048-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L2048. + */ +typedef struct icp_qat_fw_maths_modexp_l2048_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^2048 (32 qwords)*/ +} icp_qat_fw_maths_modexp_l2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 2560-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L2560. + */ +typedef struct icp_qat_fw_maths_modexp_l2560_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2560 (40 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^2560 (40 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^2560 (40 qwords)*/ +} icp_qat_fw_maths_modexp_l2560_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 3072-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L3072. + */ +typedef struct icp_qat_fw_maths_modexp_l3072_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^3072 (48 qwords)*/ +} icp_qat_fw_maths_modexp_l3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 3584-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L3584. + */ +typedef struct icp_qat_fw_maths_modexp_l3584_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3584 (56 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^3584 (56 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^3584 (56 qwords)*/ +} icp_qat_fw_maths_modexp_l3584_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers less than 4096-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L4096. + */ +typedef struct icp_qat_fw_maths_modexp_l4096_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^4096 (64 qwords)*/ +} icp_qat_fw_maths_modexp_l4096_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers up to 8192 + * bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODEXP_L8192. + */ +typedef struct icp_qat_fw_maths_modexp_l8192_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_maths_modexp_l8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less + * than 128 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_ODD_L128. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l128_input_s +{ + uint64_t a; /**< number > 0 and < 2^128 (2 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^128, coprime to a (2 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l128_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l192_input_s +{ + uint64_t a; /**< number > 0 and < 2^192 (3 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^192, coprime to a (3 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l192_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L256. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l256_input_s +{ + uint64_t a; /**< number > 0 and < 2^256 (4 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^256, coprime to a (4 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L384. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l384_input_s +{ + uint64_t a; /**< number > 0 and < 2^384 (6 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^384, coprime to a (6 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l384_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L512. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l512_input_s +{ + uint64_t a; /**< number > 0 and < 2^512 (8 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^512, coprime to a (8 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L768. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l768_input_s +{ + uint64_t a; /**< number > 0 and < 2^768 (12 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^768 ,coprime to a (12 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L1024. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l1024_input_s +{ + uint64_t a; /**< number > 0 and < 2^1024 (16 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^1024, coprime to a (16 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L1536. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l1536_input_s +{ + uint64_t a; /**< number > 0 and < 2^1536 (24 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^1536, coprime to a (24 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L2048. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l2048_input_s +{ + uint64_t a; /**< number > 0 and < 2^2048 (32 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^2048, coprime to a (32 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L3072. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l3072_input_s +{ + uint64_t a; /**< number > 0 and < 2^3072 (48 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^3072, coprime to a (48 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L4096. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l4096_input_s +{ + uint64_t a; /**< number > 0 and < 2^4096 (64 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^4096, coprime to a (64 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l4096_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_ODD_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l8192_input_s +{ + uint64_t a; /**< number > 0 and < 2^8192 (128 qwords)*/ + uint64_t + b; /**< odd modulus > 0 and < 2^8192, coprime to a (128 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less + * than 128 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_EVEN_L128. + */ +typedef struct icp_qat_fw_maths_modinv_even_l128_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^128 (2 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^128, coprime with a (2 qwords)*/ +} icp_qat_fw_maths_modinv_even_l128_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l192_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^192 (3 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^192, coprime with a (3 qwords)*/ +} icp_qat_fw_maths_modinv_even_l192_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L256. + */ +typedef struct icp_qat_fw_maths_modinv_even_l256_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^256 (4 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^256, coprime with a (4 qwords)*/ +} icp_qat_fw_maths_modinv_even_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L384. + */ +typedef struct icp_qat_fw_maths_modinv_even_l384_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^384 (6 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^384, coprime with a (6 qwords)*/ +} icp_qat_fw_maths_modinv_even_l384_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L512. + */ +typedef struct icp_qat_fw_maths_modinv_even_l512_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^512 (8 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^512, coprime with a (8 qwords)*/ +} icp_qat_fw_maths_modinv_even_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L768. + */ +typedef struct icp_qat_fw_maths_modinv_even_l768_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^768 (12 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^768, coprime with a (12 qwords)*/ +} icp_qat_fw_maths_modinv_even_l768_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L1024. + */ +typedef struct icp_qat_fw_maths_modinv_even_l1024_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^1024 (16 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^1024, coprime with a (16 qwords)*/ +} icp_qat_fw_maths_modinv_even_l1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L1536. + */ +typedef struct icp_qat_fw_maths_modinv_even_l1536_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^1536 (24 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^1536, coprime with a (24 qwords)*/ +} icp_qat_fw_maths_modinv_even_l1536_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L2048. + */ +typedef struct icp_qat_fw_maths_modinv_even_l2048_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^2048 (32 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^2048, coprime with a (32 qwords)*/ +} icp_qat_fw_maths_modinv_even_l2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L3072. + */ +typedef struct icp_qat_fw_maths_modinv_even_l3072_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^3072 (48 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^3072, coprime with a (48 qwords)*/ +} icp_qat_fw_maths_modinv_even_l3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L4096. + */ +typedef struct icp_qat_fw_maths_modinv_even_l4096_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^4096 (64 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^4096, coprime with a (64 qwords)*/ +} icp_qat_fw_maths_modinv_even_l4096_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_EVEN_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l8192_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^8192 (128 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^8192, coprime with a (128 + qwords)*/ +} icp_qat_fw_maths_modinv_even_l8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s +{ + uint64_t x; /**< DSA 1024-bit randomness (16 qwords)*/ + uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_1024. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_input_s +{ + uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ + uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ + uint64_t h; /**< DSA 1024-bit parameter (16 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_1024. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_input_s +{ + uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (160 bits), (3 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_1024_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t p; /**< DSA parameter, (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_160_input_s +{ + uint64_t m; /**< digest message to be signed (3 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t r; /**< DSA parameter (3 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_s +{ + uint64_t m; /**< digest of the message to be signed (3 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t p; /**< DSA parameter (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_input_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t m; /**< digest of the message (3 qwords)*/ + uint64_t p; /**< DSA parameter (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t y; /**< DSA parameter (16 qwords)*/ +} icp_qat_fw_mmp_dsa_verify_1024_160_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_input_s +{ + uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ + uint64_t q; /**< DSA 224-bit parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_2048. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_input_s +{ + uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (224/256 bits), (4 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_224_input_s +{ + uint64_t m; /**< digest message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t r; /**< DSA parameter (4 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_224_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_input_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t y; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_verify_2048_224_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_input_s +{ + uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_2048. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_input_s +{ + uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ + uint64_t h; /**< DSA 2048-bit parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_2048_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_256_input_s +{ + uint64_t m; /**< digest message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t r; /**< DSA parameter (4 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_input_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t y; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_verify_2048_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_input_s +{ + uint64_t x; /**< DSA 3072-bit randomness (48 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_3072. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_input_s +{ + uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ + uint64_t h; /**< DSA 3072-bit parameter (48 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_3072. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_input_s +{ + uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3072 bits), (4 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_3072_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_input_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t y; /**< DSA parameter (48 qwords)*/ +} icp_qat_fw_mmp_dsa_verify_3072_256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_s +{ + uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) (36 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_s +{ + uint64_t xg; /**< x coordinate of base point G of B/K-163 of B/K-233 (4 qwords)*/ + uint64_t yg; /**< y coordinate of base point G of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t n; /**< order of the base point of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-163 of B/K-233 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t k; /**< random value > 0 and < n (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Sign S for curves with n < 2^256 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_s +{ + uint64_t e; /**< hash of message (0 < e < 2^256) (4 qwords)*/ + uint64_t d; /**< private key (>0 and < n) (4 qwords)*/ + uint64_t r; /**< ECDSA r signature value (>0 and < n) (4 qwords)*/ + uint64_t k; /**< random value > 0 and < n (4 qwords)*/ + uint64_t n; /**< order of the base point G (2 < n < 2^256) (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_s +{ + uint64_t in; /**< concatenated curve parameter (e,s,r,n,G,Q,a,b,q) (44 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_s +{ + uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) (72 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_s +{ + uint64_t xg; /**< x coordinate of verified base point (> 0 and degree(x(G)) < degree(q)) (8 qwords)*/ + uint64_t yg; /**< y coordinate of verified base point (> 0 and degree(y(G)) < degree(q)) (8 qwords)*/ + uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and < 2^512) (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < degree(q)) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(b) < degree(q)) (8 qwords)*/ + uint64_t k; /**< random value > 0 and < n (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_s +{ + uint64_t e; /**< hash of message (0 < e < 2^512) (8 qwords)*/ + uint64_t d; /**< private key (>0 and < n) (8 qwords)*/ + uint64_t r; /**< ECDSA r signature value (>0 and < n) (8 qwords)*/ + uint64_t k; /**< random value > 0 and < n (8 qwords)*/ + uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and < 2^512) (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_s +{ + uint64_t in; /**< concatenated curve parameters (e, s, r, n, xG, yG, xQ, yQ, a, b, q) (88 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_s +{ + uint64_t in; /**< concatenated input parameters (x(G), y(G), n, q, a, b, k, e, d) (81 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_s +{ + uint64_t e; /**< hash of message < 2^576 (9 qwords)*/ + uint64_t d; /**< private key (> 0 and < n) (9 qwords)*/ + uint64_t r; /**< ECDSA r signature value (> 0 and < n) (9 qwords)*/ + uint64_t k; /**< random value (> 0 and < n) (9 qwords)*/ + uint64_t n; /**< order of the base point of the curve (n < 2^576) (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign R for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_s +{ + uint64_t xg; /**< x coordinate of verified base point belonging to B/K-571 (9 qwords)*/ + uint64_t yg; /**< y coordinate of verified base point belonging to B/K-571 (9 qwords)*/ + uint64_t n; /**< order of the base point G (9 qwords)*/ + uint64_t q; /**< irreducible field polynomial of B/K-571 (9 qwords)*/ + uint64_t a; /**< a coefficient of curve B/K-571 (degree(a) < degree(q)) (9 qwords)*/ + uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) < degree(q)) (9 qwords)*/ + uint64_t k; /**< random value > 0 and < n (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Verify for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_s +{ + uint64_t in; /**< concatenated input (e, s, r, n, G, Q, a, b, q) (99 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_input_s +{ + uint64_t k; /**< scalar multiplier > 0 and < 2^256 (4 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < 256) (4 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(yG) < 256) (4 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t h; /**< cofactor of B/K-163 or B/K-233 (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l256_input_s +{ + uint64_t xq; /**< x coordinate of input point (4 qwords)*/ + uint64_t yq; /**< y coordinate of input point (4 qwords)*/ + uint64_t q; /**< field polynomial of curve, degree(q) < 256 (4 qwords)*/ + uint64_t a; /**< a equation coefficient of curve, degree(a) < 256 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of curve, degree(b) < 256 (4 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_input_s +{ + uint64_t k; /**< scalar multiplier > 0 and < 2^512 (8 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < 512) (8 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(yG) < 512) (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(b) < 512) (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t h; /**< cofactor (< 2^512) (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l512_input_s +{ + uint64_t xq; /**< x coordinate of input point (8 qwords)*/ + uint64_t yq; /**< y coordinate of input point (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(a) < 512) (8 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GF2 Point Multiplication for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_input_s +{ + uint64_t k; /**< scalar value > 0 and < 2^576 (9 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < degree(q)) (9 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(xG) < degree(q)) (9 qwords)*/ + uint64_t a; /**< a equation coefficient for B/K-571 (9 qwords)*/ + uint64_t b; /**< b equation coefficient for B/K-571 (9 qwords)*/ + uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ + uint64_t h; /**< cofactor for B/K-571 (1 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GF2 Point Verification for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_571_input_s +{ + uint64_t xq; /**< x coordinate of candidate public key (9 qwords)*/ + uint64_t yq; /**< y coordinate of candidate public key (9 qwords)*/ + uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-571 (9 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-571 (9 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (4 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (4 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ + uint64_t k; /**< random value (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_s +{ + uint64_t e; /**< digest of the message to be signed (4 qwords)*/ + uint64_t d; /**< private key (4 qwords)*/ + uint64_t r; /**< DSA r signature value (4 qwords)*/ + uint64_t k; /**< random value (4 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (36 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (44 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (8 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (8 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ + uint64_t k; /**< random value (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_s +{ + uint64_t e; /**< digest of the message to be signed (8 qwords)*/ + uint64_t d; /**< private key (8 qwords)*/ + uint64_t r; /**< DSA r signature value (8 qwords)*/ + uint64_t k; /**< random value (8 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (72 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (88 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (9 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (9 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ + uint64_t k; /**< random value (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_s +{ + uint64_t e; /**< digest of the message to be signed (9 qwords)*/ + uint64_t d; /**< private key (9 qwords)*/ + uint64_t r; /**< DSA r signature value (9 qwords)*/ + uint64_t k; /**< random value (9 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (81 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (99 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_input_s +{ + uint64_t k; /**< scalar multiplier (4 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (4 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t h; /**< cofactor (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l256_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (4 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_input_s +{ + uint64_t k; /**< scalar multiplier (8 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (8 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t h; /**< cofactor (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Partial Point , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l512_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (8 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_input_s +{ + uint64_t k; /**< scalar multiplier (9 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (9 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t h; /**< cofactor (1 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_521_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (9 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_521_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_C25519. + */ +typedef struct icp_qat_fw_point_multiplication_c25519_input_s +{ + uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_point_multiplication_c25519_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_C25519. + */ +typedef struct icp_qat_fw_generator_multiplication_c25519_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_generator_multiplication_c25519_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_point_multiplication_ed25519_input_s +{ + uint64_t xp; /**< xP = Twisted Edwards affine coordinate X of point P (4 qwords)*/ + uint64_t yp; /**< yP = Twisted Edwards affine coordinate Y of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_point_multiplication_ed25519_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_generator_multiplication_ed25519_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_generator_multiplication_ed25519_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_C448. + */ +typedef struct icp_qat_fw_point_multiplication_c448_input_s +{ + uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (8 qwords)*/ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_point_multiplication_c448_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_C448. + */ +typedef struct icp_qat_fw_generator_multiplication_c448_input_s +{ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_generator_multiplication_c448_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_ED448. + */ +typedef struct icp_qat_fw_point_multiplication_ed448_input_s +{ + uint64_t xp; /**< xP = Edwards affine coordinate X of point P (8 qwords)*/ + uint64_t yp; /**< yP = Edwards affine coordinate Y of point P (8 qwords)*/ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_point_multiplication_ed448_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_ED448. + */ +typedef struct icp_qat_fw_generator_multiplication_ed448_input_s +{ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_generator_multiplication_ed448_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P521 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P521. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s +{ + uint64_t kpt_wrapped; /**< (42 qwords)*/ + uint64_t kpt_wrapping_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s +{ + uint64_t kpt_wrapped; /**< (42 qwords)*/ + uint64_t kpt_wrapping_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC KPT P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s +{ + uint64_t kpt_wrapped; /**< (28 qwords)*/ + uint64_t key_unwrap_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (4 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 512 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ + uint64_t kpt_wrapped; /**< (16 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_512_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 1024 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ + uint64_t kpt_wrapped; /**< (32 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 1536 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ + uint64_t kpt_wrapped; /**< (48 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 2048 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ + uint64_t kpt_wrapped; /**< (64 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 3072 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ + uint64_t kpt_wrapped; /**< (96 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 4096 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ + uint64_t kpt_wrapped; /**< (128 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for KPT RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ + uint64_t kpt_wrapped; /**< (256 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 512 decryption second form , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_KPT_RSA_DP2_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ + uint64_t kpt_wrapped; /**< (28 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_512_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_1024. + * #PKE_KPT_RSA_DP2_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1024_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (8 qwords)*/ - uint64_t dq; /**< RSA private key 0 < dq < q-1 (8 qwords)*/ - uint64_t qinv; /**< RSA private key 0 < qInv < p (8 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_1024_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ + uint64_t kpt_wrapped; /**< (56 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for RSA 1536 key generation first form , + * Input parameter list for KPT RSA 1536 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_1536. + * #PKE_KPT_RSA_DP2_1536. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1536_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^768 (12 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^768 (12 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 1536 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1536_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^767 < q < 2^768 (12 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 1536 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_1536_input_s { - uint64_t m; /**< message representative, < n (24 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ (p*q)-1 (24 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^1536 (24 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 1536 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1536_input_s { - uint64_t c; /**< cipher text representative, < n (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^1536 (24 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 1536 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1536_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (12 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (12 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (12 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 2048 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_2048_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1024 (16 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1024 (16 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 2048 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_2048_input_s { - uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 - (16 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 - (16 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 2048 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_2048_input_s { - uint64_t m; /**< message representative, < n (32 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (32 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 2048 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_2048_input_s { - uint64_t c; /**< cipher text representative, < n (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_2048_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ + uint64_t kpt_wrapped; /**< (84 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_t; /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_2048. + * #PKE_KPT_RSA_DP2_2048. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_2048_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 - (16 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 - (16 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (16 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (16 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (16 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_2048_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ + uint64_t kpt_wrapped; /**< (112 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for RSA 3072 key generation first form , + * Input parameter list for , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_3072. + * #PKE_KPT_RSA_DP2_3072. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_3072_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1536 (24 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1536 (24 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 3072 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_3072_input_s { - uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 - (24 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 - (24 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 3072 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_3072_input_s { - uint64_t m; /**< message representative, < n (48 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (48 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 3072 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_3072_input_s { - uint64_t c; /**< cipher text representative, < n (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 3072 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_3072_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 - (24 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 - (24 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (24 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (24 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (24 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 4096 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_4096_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^2048 (32 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^2048 (32 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 4096 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_4096_input_s { - uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 - (32 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 - (32 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 4096 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_4096_input_s { - uint64_t m; /**< message representative, < n (64 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (64 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for RSA 4096 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_4096_input_s { - uint64_t c; /**< cipher text representative, < n (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_4096_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ + uint64_t kpt_wrapped; /**< (168 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_t; /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_4096. + * #PKE_KPT_RSA_DP2_4096. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_4096_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 - (32 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 - (32 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (32 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (32 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (32 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_4096_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ + uint64_t kpt_wrapped; /**< (224 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for GCD primality test for 192-bit numbers , + * Input parameter list for RSA 8192 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_192. + * #PKE_KPT_RSA_DP2_8192. */ -typedef struct icp_qat_fw_mmp_gcd_pt_192_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^192 (3 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_192_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 256-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_256. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_256_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^256 (4 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 384-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_384. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_384_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^384 (6 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_384_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_512. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_512_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_768. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_768_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^768 (12 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_1024. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_1024_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^1024 (16 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_1536. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_1536_input_s { - uint64_t m; /**< (24 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_2048. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_2048_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^2048 (32 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_3072. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_3072_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^3072 (48 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for GCD primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_4096. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_4096_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_gcd_pt_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_160. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_160_input_s { - uint64_t m; /**< prime candidate, 2^159 < m < 2^160 (3 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_512. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_512_input_s { - uint64_t m; /**< prime candidate, 2^511 < m < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for <e; 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_L512. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_l512_input_s { - uint64_t m; /**< prime candidate, 5 < m < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_768. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_768_input_s { - uint64_t m; /**< prime candidate, 2^767 < m < 2^768 (12 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_1024. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_1024_input_s { - uint64_t - m; /**< prime candidate, 2^1023 < m < 2^1024 (16 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_1536. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_1536_input_s { - uint64_t - m; /**< prime candidate, 2^1535 < m < 2^1536 (24 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_2048. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_2048_input_s { - uint64_t - m; /**< prime candidate, 2^2047 < m < 2^2048 (32 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_3072. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_3072_input_s { - uint64_t - m; /**< prime candidate, 2^3071 < m < 2^3072 (48 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Fermat primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_4096. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_4096_input_s { - uint64_t - m; /**< prime candidate, 2^4095 < m < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_fermat_pt_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_160. - */ -typedef struct icp_qat_fw_mmp_mr_pt_160_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (3 qwords)*/ - uint64_t m; /**< prime candidate > 2^159 and < 2^160 (3 qwords)*/ -} icp_qat_fw_mmp_mr_pt_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_512. - */ -typedef struct icp_qat_fw_mmp_mr_pt_512_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ - uint64_t m; /**< prime candidate > 2^511 and < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_mr_pt_512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_768. - */ -typedef struct icp_qat_fw_mmp_mr_pt_768_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (12 qwords)*/ - uint64_t m; /**< prime candidate > 2^767 and < 2^768 (12 qwords)*/ -} icp_qat_fw_mmp_mr_pt_768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 1024-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_1024. - */ -typedef struct icp_qat_fw_mmp_mr_pt_1024_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (16 qwords)*/ - uint64_t - m; /**< prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ -} icp_qat_fw_mmp_mr_pt_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 1536-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_1536. - */ -typedef struct icp_qat_fw_mmp_mr_pt_1536_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (24 qwords)*/ - uint64_t - m; /**< prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ -} icp_qat_fw_mmp_mr_pt_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 2048-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_2048. - */ -typedef struct icp_qat_fw_mmp_mr_pt_2048_input_s { - uint64_t x; /**< randomness > 1 and <m-1 (32 qwords)*/ - uint64_t - m; /**< prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ -} icp_qat_fw_mmp_mr_pt_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 3072-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_3072. - */ -typedef struct icp_qat_fw_mmp_mr_pt_3072_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (48 qwords)*/ - uint64_t - m; /**< prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ -} icp_qat_fw_mmp_mr_pt_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 4096-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_4096. - */ -typedef struct icp_qat_fw_mmp_mr_pt_4096_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (64 qwords)*/ - uint64_t - m; /**< prime candidate > 2^4095 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_mmp_mr_pt_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Miller-Rabin primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_L512. - */ -typedef struct icp_qat_fw_mmp_mr_pt_l512_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ - uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_mr_pt_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_160. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_160_input_s { - uint64_t - m; /**< odd prime candidate > 2^159 and < 2^160 (3 qwords)*/ -} icp_qat_fw_mmp_lucas_pt_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_512. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_512_input_s { - uint64_t - m; /**< odd prime candidate > 2^511 and < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_lucas_pt_512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_768. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_768_input_s { - uint64_t - m; /**< odd prime candidate > 2^767 and < 2^768 (12 qwords)*/ -} icp_qat_fw_mmp_lucas_pt_768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_1024. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_1024_input_s { - uint64_t m; /**< odd prime candidate > 2^1023 and < 2^1024 (16 - qwords)*/ -} icp_qat_fw_mmp_lucas_pt_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_1536. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_1536_input_s { - uint64_t m; /**< odd prime candidate > 2^1535 and < 2^1536 (24 - qwords)*/ -} icp_qat_fw_mmp_lucas_pt_1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_2048. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_2048_input_s { - uint64_t m; /**< odd prime candidate > 2^2047 and < 2^2048 (32 - qwords)*/ -} icp_qat_fw_mmp_lucas_pt_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_3072. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_3072_input_s { - uint64_t m; /**< odd prime candidate > 2^3071 and < 2^3072 (48 - qwords)*/ -} icp_qat_fw_mmp_lucas_pt_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_4096. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_4096_input_s { - uint64_t m; /**< odd prime candidate > 2^4096 and < 2^4096 (64 - qwords)*/ -} icp_qat_fw_mmp_lucas_pt_4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Lucas primality test for L512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_L512. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_l512_input_s { - uint64_t m; /**< odd prime candidate > 5 and < 2^512 (8 qwords)*/ -} icp_qat_fw_mmp_lucas_pt_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 512-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L512. - */ -typedef struct icp_qat_fw_maths_modexp_l512_input_s { - uint64_t g; /**< base ≥ 0 and < 2^512 (8 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^512 (8 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^512 (8 qwords)*/ -} icp_qat_fw_maths_modexp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 1024-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L1024. - */ -typedef struct icp_qat_fw_maths_modexp_l1024_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^1024 (16 qwords)*/ -} icp_qat_fw_maths_modexp_l1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 1536-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L1536. - */ -typedef struct icp_qat_fw_maths_modexp_l1536_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^1536 (24 qwords)*/ -} icp_qat_fw_maths_modexp_l1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 2048-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L2048. - */ -typedef struct icp_qat_fw_maths_modexp_l2048_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^2048 (32 qwords)*/ -} icp_qat_fw_maths_modexp_l2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 2560-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L2560. - */ -typedef struct icp_qat_fw_maths_modexp_l2560_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2560 (40 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^2560 (40 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^2560 (40 qwords)*/ -} icp_qat_fw_maths_modexp_l2560_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 3072-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L3072. - */ -typedef struct icp_qat_fw_maths_modexp_l3072_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^3072 (48 qwords)*/ -} icp_qat_fw_maths_modexp_l3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 3584-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L3584. - */ -typedef struct icp_qat_fw_maths_modexp_l3584_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3584 (56 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^3584 (56 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^3584 (56 qwords)*/ -} icp_qat_fw_maths_modexp_l3584_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 4096-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L4096. - */ -typedef struct icp_qat_fw_maths_modexp_l4096_input_s { - uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^4096 (64 qwords)*/ -} icp_qat_fw_maths_modexp_l4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L128. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l128_input_s { - uint64_t a; /**< number > 0 and < 2^128 (2 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^128, coprime to a (2 qwords)*/ -} icp_qat_fw_maths_modinv_odd_l128_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L192. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l192_input_s { - uint64_t a; /**< number > 0 and < 2^192 (3 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^192, coprime to a (3 qwords)*/ -} icp_qat_fw_maths_modinv_odd_l192_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L256. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l256_input_s { - uint64_t a; /**< number > 0 and < 2^256 (4 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^256, coprime to a (4 qwords)*/ -} icp_qat_fw_maths_modinv_odd_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L384. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l384_input_s { - uint64_t a; /**< number > 0 and < 2^384 (6 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^384, coprime to a (6 qwords)*/ -} icp_qat_fw_maths_modinv_odd_l384_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L512. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l512_input_s { - uint64_t a; /**< number > 0 and < 2^512 (8 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^512, coprime to a (8 qwords)*/ -} icp_qat_fw_maths_modinv_odd_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L768. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l768_input_s { - uint64_t a; /**< number > 0 and < 2^768 (12 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^768 ,coprime to a (12 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L1024. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l1024_input_s { - uint64_t a; /**< number > 0 and < 2^1024 (16 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^1024, coprime to a (16 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L1536. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l1536_input_s { - uint64_t a; /**< number > 0 and < 2^1536 (24 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^1536, coprime to a (24 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L2048. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l2048_input_s { - uint64_t a; /**< number > 0 and < 2^2048 (32 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^2048, coprime to a (32 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L3072. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l3072_input_s { - uint64_t a; /**< number > 0 and < 2^3072 (48 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^3072, coprime to a (48 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L4096. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l4096_input_s { - uint64_t a; /**< number > 0 and < 2^4096 (64 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^4096, coprime to a (64 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L128. - */ -typedef struct icp_qat_fw_maths_modinv_even_l128_input_s { - uint64_t a; /**< odd number > 0 and < 2^128 (2 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^128, coprime with a (2 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l128_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L192. - */ -typedef struct icp_qat_fw_maths_modinv_even_l192_input_s { - uint64_t a; /**< odd number > 0 and < 2^192 (3 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^192, coprime with a (3 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l192_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L256. - */ -typedef struct icp_qat_fw_maths_modinv_even_l256_input_s { - uint64_t a; /**< odd number > 0 and < 2^256 (4 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^256, coprime with a (4 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L384. - */ -typedef struct icp_qat_fw_maths_modinv_even_l384_input_s { - uint64_t a; /**< odd number > 0 and < 2^384 (6 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^384, coprime with a (6 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l384_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L512. - */ -typedef struct icp_qat_fw_maths_modinv_even_l512_input_s { - uint64_t a; /**< odd number > 0 and < 2^512 (8 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^512, coprime with a (8 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L768. - */ -typedef struct icp_qat_fw_maths_modinv_even_l768_input_s { - uint64_t a; /**< odd number > 0 and < 2^768 (12 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^768, coprime with a - (12 qwords)*/ -} icp_qat_fw_maths_modinv_even_l768_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L1024. - */ -typedef struct icp_qat_fw_maths_modinv_even_l1024_input_s { - uint64_t a; /**< odd number > 0 and < 2^1024 (16 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^1024, coprime with a - (16 qwords)*/ -} icp_qat_fw_maths_modinv_even_l1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L1536. - */ -typedef struct icp_qat_fw_maths_modinv_even_l1536_input_s { - uint64_t a; /**< odd number > 0 and < 2^1536 (24 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^1536, coprime with a - (24 qwords)*/ -} icp_qat_fw_maths_modinv_even_l1536_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L2048. - */ -typedef struct icp_qat_fw_maths_modinv_even_l2048_input_s { - uint64_t a; /**< odd number > 0 and < 2^2048 (32 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^2048, coprime with a - (32 qwords)*/ -} icp_qat_fw_maths_modinv_even_l2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L3072. - */ -typedef struct icp_qat_fw_maths_modinv_even_l3072_input_s { - uint64_t a; /**< odd number > 0 and < 2^3072 (48 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^3072, coprime with a - (48 qwords)*/ -} icp_qat_fw_maths_modinv_even_l3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L4096. - */ -typedef struct icp_qat_fw_maths_modinv_even_l4096_input_s { - uint64_t a; /**< odd number > 0 and < 2^4096 (64 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^4096, coprime with a - (64 qwords)*/ -} icp_qat_fw_maths_modinv_even_l4096_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s { - uint64_t x; /**< DSA 1024-bit randomness (16 qwords)*/ - uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_1024. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_input_s { - uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ - uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ - uint64_t h; /**< DSA 1024-bit parameter (16 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_1024. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_input_s { - uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t - x; /**< randomly generated DSA parameter (160 bits), (3 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_1024_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_input_s { - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t p; /**< DSA parameter, (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_160_input_s { - uint64_t m; /**< digest message to be signed (3 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t r; /**< DSA parameter (3 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_s { - uint64_t m; /**< digest of the message to be signed (3 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t p; /**< DSA parameter (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_input_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t m; /**< digest of the message (3 qwords)*/ - uint64_t p; /**< DSA parameter (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t y; /**< DSA parameter (16 qwords)*/ -} icp_qat_fw_mmp_dsa_verify_1024_160_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_input_s { - uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ - uint64_t q; /**< DSA 224-bit parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_2048. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_input_s { - uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (224/256 bits), (4 - qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_224_input_s { - uint64_t m; /**< digest message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t r; /**< DSA parameter (4 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_224_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_input_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t y; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_verify_2048_224_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_input_s { - uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_2048. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_input_s { - uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ - uint64_t h; /**< DSA 2048-bit parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_2048_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_256_input_s { - uint64_t m; /**< digest message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t r; /**< DSA parameter (4 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_input_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t y; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_verify_2048_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_input_s { - uint64_t x; /**< DSA 3072-bit randomness (48 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_3072. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_input_s { - uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ - uint64_t h; /**< DSA 3072-bit parameter (48 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_3072. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_input_s { - uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t - x; /**< randomly generated DSA parameter (3072 bits), (4 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_3072_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_input_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t y; /**< DSA parameter (48 qwords)*/ -} icp_qat_fw_mmp_dsa_verify_3072_256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_s { - uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) - (36 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_s { - uint64_t - xg; /**< x coordinate of base point G of B/K-163 of B/K-233 (4 - qwords)*/ - uint64_t - yg; /**< y coordinate of base point G of B/K-163 or B/K-233 (4 - qwords)*/ - uint64_t - n; /**< order of the base point of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t - a; /**< a equation coefficient of B/K-163 of B/K-233 (4 qwords)*/ - uint64_t - b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t k; /**< random value > 0 and < n (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA Sign S for curves with n < 2^256 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_s { - uint64_t e; /**< hash of message (0 < e < 2^256) (4 qwords)*/ - uint64_t d; /**< private key (>0 and < n) (4 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (>0 and < n) (4 qwords)*/ - uint64_t k; /**< random value > 0 and < n (4 qwords)*/ - uint64_t n; /**< order of the base point G (2 < n < 2^256) (4 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_s { - uint64_t - in; /**< concatenated curve parameter (e,s,r,n,G,Q,a,b,q) (44 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_s { - uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) - (72 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_s { - uint64_t xg; /**< x coordinate of verified base point (> 0 and - degree(x(G)) < degree(q)) (8 qwords)*/ - uint64_t yg; /**< y coordinate of verified base point (> 0 and - degree(y(G)) < degree(q)) (8 qwords)*/ - uint64_t n; /**< order of the base point G, which must be prime and a - divisor of #E and < 2^512) (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t a; /**< a equation coefficient (degree(a) < degree(q)) (8 - qwords)*/ - uint64_t b; /**< b equation coefficient (degree(b) < degree(q)) (8 - qwords)*/ - uint64_t k; /**< random value > 0 and < n (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_s { - uint64_t e; /**< hash of message (0 < e < 2^512) (8 qwords)*/ - uint64_t d; /**< private key (>0 and < n) (8 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (>0 and < n) (8 qwords)*/ - uint64_t k; /**< random value > 0 and < n (8 qwords)*/ - uint64_t n; /**< order of the base point G, which must be prime and a - divisor of #E and < 2^512) (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_s { - uint64_t - in; /**< concatenated curve parameters (e, s, r, n, xG, yG, xQ, yQ, - a, b, q) (88 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_s { - uint64_t - in; /**< concatenated input parameters (x(G), y(G), n, q, a, b, k, - e, d) (81 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_s { - uint64_t e; /**< hash of message < 2^576 (9 qwords)*/ - uint64_t d; /**< private key (> 0 and < n) (9 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (> 0 and < n) (9 qwords)*/ - uint64_t k; /**< random value (> 0 and < n) (9 qwords)*/ - uint64_t - n; /**< order of the base point of the curve (n < 2^576) (9 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Sign R for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_s { - uint64_t xg; /**< x coordinate of verified base point belonging to - B/K-571 (9 qwords)*/ - uint64_t yg; /**< y coordinate of verified base point belonging to - B/K-571 (9 qwords)*/ - uint64_t n; /**< order of the base point G (9 qwords)*/ - uint64_t q; /**< irreducible field polynomial of B/K-571 (9 qwords)*/ - uint64_t a; /**< a coefficient of curve B/K-571 (degree(a) < - degree(q)) (9 qwords)*/ - uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) < - degree(q)) (9 qwords)*/ - uint64_t k; /**< random value > 0 and < n (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GF2 Verify for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_s { - uint64_t in; /**< concatenated input (e, s, r, n, G, Q, a, b, q) (99 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_input_s { - uint64_t k; /**< scalar multiplier > 0 and < 2^256 (4 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < 256) (4 - qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(yG) < 256) (4 - qwords)*/ - uint64_t - a; /**< a equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t - b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t h; /**< cofactor of B/K-163 or B/K-233 (4 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l256_input_s { - uint64_t xq; /**< x coordinate of input point (4 qwords)*/ - uint64_t yq; /**< y coordinate of input point (4 qwords)*/ - uint64_t - q; /**< field polynomial of curve, degree(q) < 256 (4 qwords)*/ - uint64_t - a; /**< a equation coefficient of curve, degree(a) < 256 (4 - qwords)*/ - uint64_t - b; /**< b equation coefficient of curve, degree(b) < 256 (4 - qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_input_s { - uint64_t k; /**< scalar multiplier > 0 and < 2^512 (8 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < 512) (8 - qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(yG) < 512) (8 - qwords)*/ - uint64_t - a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ - uint64_t - b; /**< b equation coefficient (degree(b) < 512) (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t h; /**< cofactor (< 2^512) (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l512_input_s { - uint64_t xq; /**< x coordinate of input point (8 qwords)*/ - uint64_t yq; /**< y coordinate of input point (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t - a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ - uint64_t - b; /**< b equation coefficient (degree(a) < 512) (8 qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GF2 Point Multiplication for curves - * B-571/K-571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_input_s { - uint64_t k; /**< scalar value > 0 and < 2^576 (9 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < - degree(q)) (9 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(xG) < - degree(q)) (9 qwords)*/ - uint64_t a; /**< a equation coefficient for B/K-571 (9 qwords)*/ - uint64_t b; /**< b equation coefficient for B/K-571 (9 qwords)*/ - uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ - uint64_t h; /**< cofactor for B/K-571 (1 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GF2 Point Verification for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_571_input_s { - uint64_t xq; /**< x coordinate of candidate public key (9 qwords)*/ - uint64_t yq; /**< y coordinate of candidate public key (9 qwords)*/ - uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ - uint64_t a; /**< a equation coefficient of B/K-571 (9 qwords)*/ - uint64_t b; /**< b equation coefficient of B/K-571 (9 qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_571_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_s { - uint64_t xg; /**< x coordinate of base point G, (4 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (4 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (4 - qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ - uint64_t k; /**< random value (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_s { - uint64_t e; /**< digest of the message to be signed (4 qwords)*/ - uint64_t d; /**< private key (4 qwords)*/ - uint64_t r; /**< DSA r signature value (4 qwords)*/ - uint64_t k; /**< random value (4 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (4 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (36 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (44 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_s { - uint64_t xg; /**< x coordinate of base point G, (8 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (8 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (8 - qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ - uint64_t k; /**< random value (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_s { - uint64_t e; /**< digest of the message to be signed (8 qwords)*/ - uint64_t d; /**< private key (8 qwords)*/ - uint64_t r; /**< DSA r signature value (8 qwords)*/ - uint64_t k; /**< random value (8 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (8 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (72 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (88 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_s { - uint64_t xg; /**< x coordinate of base point G, (9 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (9 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (9 - qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ - uint64_t k; /**< random value (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_s { - uint64_t e; /**< digest of the message to be signed (9 qwords)*/ - uint64_t d; /**< private key (9 qwords)*/ - uint64_t r; /**< DSA r signature value (9 qwords)*/ - uint64_t k; /**< random value (9 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (9 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (81 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (99 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_input_s { - uint64_t k; /**< scalar multiplier (4 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (4 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t h; /**< cofactor (4 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l256_input_s { - uint64_t xq; /**< x coordinate of candidate point (4 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (4 qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_l256_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_input_s { - uint64_t k; /**< scalar multiplier (8 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (8 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t h; /**< cofactor (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Partial Point , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l512_input_s { - uint64_t xq; /**< x coordinate of candidate point (8 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (8 qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_l512_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_input_s { - uint64_t k; /**< scalar multiplier (9 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (9 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t h; /**< cofactor (1 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_521_input_s { - uint64_t xq; /**< x coordinate of candidate point (9 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (9 qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_521_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC curve25519 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_C25519. - */ -typedef struct icp_qat_fw_point_multiplication_c25519_input_s { - uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (4 - qwords)*/ - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_point_multiplication_c25519_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC curve25519 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C25519. - */ -typedef struct icp_qat_fw_generator_multiplication_c25519_input_s { - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_generator_multiplication_c25519_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC edwards25519 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_point_multiplication_ed25519_input_s { - uint64_t xp; /**< xP = Twisted Edwards affine coordinate X of point P - (4 qwords)*/ - uint64_t yp; /**< yP = Twisted Edwards affine coordinate Y of point P - (4 qwords)*/ - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_point_multiplication_ed25519_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC edwards25519 Generator Point Multiplication - * [k]G, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_generator_multiplication_ed25519_input_s { - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_generator_multiplication_ed25519_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC curve448 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_C448. - */ -typedef struct icp_qat_fw_point_multiplication_c448_input_s { - uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (8 - qwords)*/ - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_point_multiplication_c448_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC curve448 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C448. - */ -typedef struct icp_qat_fw_generator_multiplication_c448_input_s { - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_generator_multiplication_c448_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC edwards448 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_ED448. - */ -typedef struct icp_qat_fw_point_multiplication_ed448_input_s { - uint64_t - xp; /**< xP = Edwards affine coordinate X of point P (8 qwords)*/ - uint64_t - yp; /**< yP = Edwards affine coordinate Y of point P (8 qwords)*/ - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_point_multiplication_ed448_input_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Input parameter list for ECC edwards448 Generator Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED448. - */ -typedef struct icp_qat_fw_generator_multiplication_ed448_input_s { - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_generator_multiplication_ed448_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (128 qwords)*/ + uint64_t kpt_wrapped; /**< (448 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_t; /** * @ingroup icp_qat_fw_mmp * @brief * MMP input parameters */ -typedef union icp_qat_fw_mmp_input_param_u { - /** Generic parameter structure : All members of this wrapper structure - * are pointers to large integers. - */ - uint64_t flat_array[ICP_QAT_FW_PKE_INPUT_COUNT_MAX]; +typedef union icp_qat_fw_mmp_input_param_u +{ + /** Generic parameter structure : All members of this wrapper structure + * are pointers to large integers. + */ + uint64_t flat_array[ICP_QAT_FW_PKE_INPUT_COUNT_MAX]; + /** ECC P384 Variable Point Multiplication [k]P */ - /** Initialisation sequence */ - icp_qat_fw_mmp_init_input_t mmp_init; + icp_qat_fw_mmp_ec_point_multiplication_p384_input_t + mmp_ec_point_multiplication_p384; - /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ - icp_qat_fw_mmp_dh_g2_768_input_t mmp_dh_g2_768; + /** ECC P384 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p384_input_t + mmp_ec_generator_multiplication_p384; - /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ - icp_qat_fw_mmp_dh_768_input_t mmp_dh_768; + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_t mmp_ecdsa_sign_rs_p384; - /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ - icp_qat_fw_mmp_dh_g2_1024_input_t mmp_dh_g2_1024; + /** ECC P256 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p256_input_t + mmp_ec_point_multiplication_p256; - /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ - icp_qat_fw_mmp_dh_1024_input_t mmp_dh_1024; + /** ECC P256 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p256_input_t + mmp_ec_generator_multiplication_p256; - /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ - icp_qat_fw_mmp_dh_g2_1536_input_t mmp_dh_g2_1536; + /** ECC P256 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_t mmp_ecdsa_sign_rs_p256; - /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ - icp_qat_fw_mmp_dh_1536_input_t mmp_dh_1536; + /** Initialisation sequence */ + icp_qat_fw_mmp_init_input_t mmp_init; - /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ - icp_qat_fw_mmp_dh_g2_2048_input_t mmp_dh_g2_2048; + /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ + icp_qat_fw_mmp_dh_g2_768_input_t mmp_dh_g2_768; - /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ - icp_qat_fw_mmp_dh_2048_input_t mmp_dh_2048; + /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ + icp_qat_fw_mmp_dh_768_input_t mmp_dh_768; - /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ - icp_qat_fw_mmp_dh_g2_3072_input_t mmp_dh_g2_3072; + /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ + icp_qat_fw_mmp_dh_g2_1024_input_t mmp_dh_g2_1024; - /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ - icp_qat_fw_mmp_dh_3072_input_t mmp_dh_3072; + /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ + icp_qat_fw_mmp_dh_1024_input_t mmp_dh_1024; - /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ - icp_qat_fw_mmp_dh_g2_4096_input_t mmp_dh_g2_4096; + /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ + icp_qat_fw_mmp_dh_g2_1536_input_t mmp_dh_g2_1536; - /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ - icp_qat_fw_mmp_dh_4096_input_t mmp_dh_4096; + /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ + icp_qat_fw_mmp_dh_1536_input_t mmp_dh_1536; - /** RSA 512 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_512_input_t mmp_rsa_kp1_512; + /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ + icp_qat_fw_mmp_dh_g2_2048_input_t mmp_dh_g2_2048; - /** RSA 512 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_512_input_t mmp_rsa_kp2_512; + /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ + icp_qat_fw_mmp_dh_2048_input_t mmp_dh_2048; - /** RSA 512 Encryption */ - icp_qat_fw_mmp_rsa_ep_512_input_t mmp_rsa_ep_512; + /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ + icp_qat_fw_mmp_dh_g2_3072_input_t mmp_dh_g2_3072; - /** RSA 512 Decryption */ - icp_qat_fw_mmp_rsa_dp1_512_input_t mmp_rsa_dp1_512; + /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ + icp_qat_fw_mmp_dh_3072_input_t mmp_dh_3072; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_512_input_t mmp_rsa_dp2_512; + /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ + icp_qat_fw_mmp_dh_g2_4096_input_t mmp_dh_g2_4096; - /** RSA 1024 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1024_input_t mmp_rsa_kp1_1024; + /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ + icp_qat_fw_mmp_dh_4096_input_t mmp_dh_4096; - /** RSA 1024 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1024_input_t mmp_rsa_kp2_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 8192-bit numbers */ + icp_qat_fw_mmp_dh_g2_8192_input_t mmp_dh_g2_8192; - /** RSA 1024 Encryption */ - icp_qat_fw_mmp_rsa_ep_1024_input_t mmp_rsa_ep_1024; + /** Diffie-Hellman Modular exponentiation for 8192-bit numbers */ + icp_qat_fw_mmp_dh_8192_input_t mmp_dh_8192; - /** RSA 1024 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1024_input_t mmp_rsa_dp1_1024; + /** RSA 512 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_512_input_t mmp_rsa_kp1_512; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1024_input_t mmp_rsa_dp2_1024; + /** RSA 512 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_512_input_t mmp_rsa_kp2_512; - /** RSA 1536 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1536_input_t mmp_rsa_kp1_1536; + /** RSA 512 Encryption */ + icp_qat_fw_mmp_rsa_ep_512_input_t mmp_rsa_ep_512; - /** RSA 1536 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1536_input_t mmp_rsa_kp2_1536; + /** RSA 512 Decryption */ + icp_qat_fw_mmp_rsa_dp1_512_input_t mmp_rsa_dp1_512; - /** RSA 1536 Encryption */ - icp_qat_fw_mmp_rsa_ep_1536_input_t mmp_rsa_ep_1536; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_512_input_t mmp_rsa_dp2_512; - /** RSA 1536 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1536_input_t mmp_rsa_dp1_1536; + /** RSA 1024 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1024_input_t mmp_rsa_kp1_1024; - /** RSA 1536 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1536_input_t mmp_rsa_dp2_1536; + /** RSA 1024 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1024_input_t mmp_rsa_kp2_1024; - /** RSA 2048 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_2048_input_t mmp_rsa_kp1_2048; + /** RSA 1024 Encryption */ + icp_qat_fw_mmp_rsa_ep_1024_input_t mmp_rsa_ep_1024; - /** RSA 2048 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_2048_input_t mmp_rsa_kp2_2048; + /** RSA 1024 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1024_input_t mmp_rsa_dp1_1024; - /** RSA 2048 Encryption */ - icp_qat_fw_mmp_rsa_ep_2048_input_t mmp_rsa_ep_2048; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1024_input_t mmp_rsa_dp2_1024; - /** RSA 2048 Decryption */ - icp_qat_fw_mmp_rsa_dp1_2048_input_t mmp_rsa_dp1_2048; + /** RSA 1536 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1536_input_t mmp_rsa_kp1_1536; - /** RSA 2048 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_2048_input_t mmp_rsa_dp2_2048; + /** RSA 1536 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1536_input_t mmp_rsa_kp2_1536; - /** RSA 3072 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_3072_input_t mmp_rsa_kp1_3072; + /** RSA 1536 Encryption */ + icp_qat_fw_mmp_rsa_ep_1536_input_t mmp_rsa_ep_1536; - /** RSA 3072 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_3072_input_t mmp_rsa_kp2_3072; + /** RSA 1536 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1536_input_t mmp_rsa_dp1_1536; - /** RSA 3072 Encryption */ - icp_qat_fw_mmp_rsa_ep_3072_input_t mmp_rsa_ep_3072; + /** RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1536_input_t mmp_rsa_dp2_1536; - /** RSA 3072 Decryption */ - icp_qat_fw_mmp_rsa_dp1_3072_input_t mmp_rsa_dp1_3072; + /** RSA 2048 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_2048_input_t mmp_rsa_kp1_2048; - /** RSA 3072 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_3072_input_t mmp_rsa_dp2_3072; + /** RSA 2048 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_2048_input_t mmp_rsa_kp2_2048; - /** RSA 4096 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_4096_input_t mmp_rsa_kp1_4096; + /** RSA 2048 Encryption */ + icp_qat_fw_mmp_rsa_ep_2048_input_t mmp_rsa_ep_2048; - /** RSA 4096 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_4096_input_t mmp_rsa_kp2_4096; + /** RSA 2048 Decryption */ + icp_qat_fw_mmp_rsa_dp1_2048_input_t mmp_rsa_dp1_2048; - /** RSA 4096 Encryption */ - icp_qat_fw_mmp_rsa_ep_4096_input_t mmp_rsa_ep_4096; + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_2048_input_t mmp_rsa_dp2_2048; - /** RSA 4096 Decryption */ - icp_qat_fw_mmp_rsa_dp1_4096_input_t mmp_rsa_dp1_4096; + /** RSA 3072 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_3072_input_t mmp_rsa_kp1_3072; - /** RSA 4096 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_4096_input_t mmp_rsa_dp2_4096; + /** RSA 3072 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_3072_input_t mmp_rsa_kp2_3072; - /** GCD primality test for 192-bit numbers */ - icp_qat_fw_mmp_gcd_pt_192_input_t mmp_gcd_pt_192; + /** RSA 3072 Encryption */ + icp_qat_fw_mmp_rsa_ep_3072_input_t mmp_rsa_ep_3072; - /** GCD primality test for 256-bit numbers */ - icp_qat_fw_mmp_gcd_pt_256_input_t mmp_gcd_pt_256; + /** RSA 3072 Decryption */ + icp_qat_fw_mmp_rsa_dp1_3072_input_t mmp_rsa_dp1_3072; - /** GCD primality test for 384-bit numbers */ - icp_qat_fw_mmp_gcd_pt_384_input_t mmp_gcd_pt_384; + /** RSA 3072 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_3072_input_t mmp_rsa_dp2_3072; - /** GCD primality test for 512-bit numbers */ - icp_qat_fw_mmp_gcd_pt_512_input_t mmp_gcd_pt_512; + /** RSA 4096 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_4096_input_t mmp_rsa_kp1_4096; - /** GCD primality test for 768-bit numbers */ - icp_qat_fw_mmp_gcd_pt_768_input_t mmp_gcd_pt_768; + /** RSA 4096 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_4096_input_t mmp_rsa_kp2_4096; - /** GCD primality test for 1024-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1024_input_t mmp_gcd_pt_1024; + /** RSA 4096 Encryption */ + icp_qat_fw_mmp_rsa_ep_4096_input_t mmp_rsa_ep_4096; - /** GCD primality test for 1536-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1536_input_t mmp_gcd_pt_1536; + /** RSA 4096 Decryption */ + icp_qat_fw_mmp_rsa_dp1_4096_input_t mmp_rsa_dp1_4096; - /** GCD primality test for 2048-bit numbers */ - icp_qat_fw_mmp_gcd_pt_2048_input_t mmp_gcd_pt_2048; + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_4096_input_t mmp_rsa_dp2_4096; - /** GCD primality test for 3072-bit numbers */ - icp_qat_fw_mmp_gcd_pt_3072_input_t mmp_gcd_pt_3072; + /** RSA 8192 Encryption */ + icp_qat_fw_mmp_rsa_ep_8192_input_t mmp_rsa_ep_8192; - /** GCD primality test for 4096-bit numbers */ - icp_qat_fw_mmp_gcd_pt_4096_input_t mmp_gcd_pt_4096; + /** RSA 8192 Decryption */ + icp_qat_fw_mmp_rsa_dp1_8192_input_t mmp_rsa_dp1_8192; - /** Fermat primality test for 160-bit numbers */ - icp_qat_fw_mmp_fermat_pt_160_input_t mmp_fermat_pt_160; + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_8192_input_t mmp_rsa_dp2_8192; - /** Fermat primality test for 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_512_input_t mmp_fermat_pt_512; + /** GCD primality test for 192-bit numbers */ + icp_qat_fw_mmp_gcd_pt_192_input_t mmp_gcd_pt_192; - /** Fermat primality test for <e; 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_l512_input_t mmp_fermat_pt_l512; + /** GCD primality test for 256-bit numbers */ + icp_qat_fw_mmp_gcd_pt_256_input_t mmp_gcd_pt_256; - /** Fermat primality test for 768-bit numbers */ - icp_qat_fw_mmp_fermat_pt_768_input_t mmp_fermat_pt_768; + /** GCD primality test for 384-bit numbers */ + icp_qat_fw_mmp_gcd_pt_384_input_t mmp_gcd_pt_384; - /** Fermat primality test for 1024-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1024_input_t mmp_fermat_pt_1024; + /** GCD primality test for 512-bit numbers */ + icp_qat_fw_mmp_gcd_pt_512_input_t mmp_gcd_pt_512; - /** Fermat primality test for 1536-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1536_input_t mmp_fermat_pt_1536; + /** GCD primality test for 768-bit numbers */ + icp_qat_fw_mmp_gcd_pt_768_input_t mmp_gcd_pt_768; - /** Fermat primality test for 2048-bit numbers */ - icp_qat_fw_mmp_fermat_pt_2048_input_t mmp_fermat_pt_2048; + /** GCD primality test for 1024-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1024_input_t mmp_gcd_pt_1024; - /** Fermat primality test for 3072-bit numbers */ - icp_qat_fw_mmp_fermat_pt_3072_input_t mmp_fermat_pt_3072; + /** GCD primality test for 1536-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1536_input_t mmp_gcd_pt_1536; - /** Fermat primality test for 4096-bit numbers */ - icp_qat_fw_mmp_fermat_pt_4096_input_t mmp_fermat_pt_4096; + /** GCD primality test for 2048-bit numbers */ + icp_qat_fw_mmp_gcd_pt_2048_input_t mmp_gcd_pt_2048; - /** Miller-Rabin primality test for 160-bit numbers */ - icp_qat_fw_mmp_mr_pt_160_input_t mmp_mr_pt_160; + /** GCD primality test for 3072-bit numbers */ + icp_qat_fw_mmp_gcd_pt_3072_input_t mmp_gcd_pt_3072; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_512_input_t mmp_mr_pt_512; + /** GCD primality test for 4096-bit numbers */ + icp_qat_fw_mmp_gcd_pt_4096_input_t mmp_gcd_pt_4096; - /** Miller-Rabin primality test for 768-bit numbers */ - icp_qat_fw_mmp_mr_pt_768_input_t mmp_mr_pt_768; + /** Fermat primality test for 160-bit numbers */ + icp_qat_fw_mmp_fermat_pt_160_input_t mmp_fermat_pt_160; - /** Miller-Rabin primality test for 1024-bit numbers */ - icp_qat_fw_mmp_mr_pt_1024_input_t mmp_mr_pt_1024; + /** Fermat primality test for 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_512_input_t mmp_fermat_pt_512; - /** Miller-Rabin primality test for 1536-bit numbers */ - icp_qat_fw_mmp_mr_pt_1536_input_t mmp_mr_pt_1536; + /** Fermat primality test for <e; 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_l512_input_t mmp_fermat_pt_l512; - /** Miller-Rabin primality test for 2048-bit numbers */ - icp_qat_fw_mmp_mr_pt_2048_input_t mmp_mr_pt_2048; + /** Fermat primality test for 768-bit numbers */ + icp_qat_fw_mmp_fermat_pt_768_input_t mmp_fermat_pt_768; - /** Miller-Rabin primality test for 3072-bit numbers */ - icp_qat_fw_mmp_mr_pt_3072_input_t mmp_mr_pt_3072; + /** Fermat primality test for 1024-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1024_input_t mmp_fermat_pt_1024; - /** Miller-Rabin primality test for 4096-bit numbers */ - icp_qat_fw_mmp_mr_pt_4096_input_t mmp_mr_pt_4096; + /** Fermat primality test for 1536-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1536_input_t mmp_fermat_pt_1536; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_l512_input_t mmp_mr_pt_l512; + /** Fermat primality test for 2048-bit numbers */ + icp_qat_fw_mmp_fermat_pt_2048_input_t mmp_fermat_pt_2048; - /** Lucas primality test for 160-bit numbers */ - icp_qat_fw_mmp_lucas_pt_160_input_t mmp_lucas_pt_160; + /** Fermat primality test for 3072-bit numbers */ + icp_qat_fw_mmp_fermat_pt_3072_input_t mmp_fermat_pt_3072; - /** Lucas primality test for 512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_512_input_t mmp_lucas_pt_512; + /** Fermat primality test for 4096-bit numbers */ + icp_qat_fw_mmp_fermat_pt_4096_input_t mmp_fermat_pt_4096; - /** Lucas primality test for 768-bit numbers */ - icp_qat_fw_mmp_lucas_pt_768_input_t mmp_lucas_pt_768; + /** Miller-Rabin primality test for 160-bit numbers */ + icp_qat_fw_mmp_mr_pt_160_input_t mmp_mr_pt_160; - /** Lucas primality test for 1024-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1024_input_t mmp_lucas_pt_1024; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_512_input_t mmp_mr_pt_512; - /** Lucas primality test for 1536-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1536_input_t mmp_lucas_pt_1536; + /** Miller-Rabin primality test for 768-bit numbers */ + icp_qat_fw_mmp_mr_pt_768_input_t mmp_mr_pt_768; - /** Lucas primality test for 2048-bit numbers */ - icp_qat_fw_mmp_lucas_pt_2048_input_t mmp_lucas_pt_2048; + /** Miller-Rabin primality test for 1024-bit numbers */ + icp_qat_fw_mmp_mr_pt_1024_input_t mmp_mr_pt_1024; - /** Lucas primality test for 3072-bit numbers */ - icp_qat_fw_mmp_lucas_pt_3072_input_t mmp_lucas_pt_3072; + /** Miller-Rabin primality test for 1536-bit numbers */ + icp_qat_fw_mmp_mr_pt_1536_input_t mmp_mr_pt_1536; - /** Lucas primality test for 4096-bit numbers */ - icp_qat_fw_mmp_lucas_pt_4096_input_t mmp_lucas_pt_4096; + /** Miller-Rabin primality test for 2048-bit numbers */ + icp_qat_fw_mmp_mr_pt_2048_input_t mmp_mr_pt_2048; - /** Lucas primality test for L512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_l512_input_t mmp_lucas_pt_l512; + /** Miller-Rabin primality test for 3072-bit numbers */ + icp_qat_fw_mmp_mr_pt_3072_input_t mmp_mr_pt_3072; - /** Modular exponentiation for numbers less than 512-bits */ - icp_qat_fw_maths_modexp_l512_input_t maths_modexp_l512; + /** Miller-Rabin primality test for 4096-bit numbers */ + icp_qat_fw_mmp_mr_pt_4096_input_t mmp_mr_pt_4096; - /** Modular exponentiation for numbers less than 1024-bit */ - icp_qat_fw_maths_modexp_l1024_input_t maths_modexp_l1024; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_l512_input_t mmp_mr_pt_l512; - /** Modular exponentiation for numbers less than 1536-bits */ - icp_qat_fw_maths_modexp_l1536_input_t maths_modexp_l1536; + /** Lucas primality test for 160-bit numbers */ + icp_qat_fw_mmp_lucas_pt_160_input_t mmp_lucas_pt_160; - /** Modular exponentiation for numbers less than 2048-bit */ - icp_qat_fw_maths_modexp_l2048_input_t maths_modexp_l2048; + /** Lucas primality test for 512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_512_input_t mmp_lucas_pt_512; - /** Modular exponentiation for numbers less than 2560-bits */ - icp_qat_fw_maths_modexp_l2560_input_t maths_modexp_l2560; + /** Lucas primality test for 768-bit numbers */ + icp_qat_fw_mmp_lucas_pt_768_input_t mmp_lucas_pt_768; - /** Modular exponentiation for numbers less than 3072-bits */ - icp_qat_fw_maths_modexp_l3072_input_t maths_modexp_l3072; + /** Lucas primality test for 1024-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1024_input_t mmp_lucas_pt_1024; - /** Modular exponentiation for numbers less than 3584-bits */ - icp_qat_fw_maths_modexp_l3584_input_t maths_modexp_l3584; + /** Lucas primality test for 1536-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1536_input_t mmp_lucas_pt_1536; - /** Modular exponentiation for numbers less than 4096-bit */ - icp_qat_fw_maths_modexp_l4096_input_t maths_modexp_l4096; + /** Lucas primality test for 2048-bit numbers */ + icp_qat_fw_mmp_lucas_pt_2048_input_t mmp_lucas_pt_2048; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_odd_l128_input_t maths_modinv_odd_l128; + /** Lucas primality test for 3072-bit numbers */ + icp_qat_fw_mmp_lucas_pt_3072_input_t mmp_lucas_pt_3072; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_odd_l192_input_t maths_modinv_odd_l192; + /** Lucas primality test for 4096-bit numbers */ + icp_qat_fw_mmp_lucas_pt_4096_input_t mmp_lucas_pt_4096; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_odd_l256_input_t maths_modinv_odd_l256; + /** Lucas primality test for L512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_l512_input_t mmp_lucas_pt_l512; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_odd_l384_input_t maths_modinv_odd_l384; + /** Modular exponentiation for numbers less than 512-bits */ + icp_qat_fw_maths_modexp_l512_input_t maths_modexp_l512; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_odd_l512_input_t maths_modinv_odd_l512; + /** Modular exponentiation for numbers less than 1024-bit */ + icp_qat_fw_maths_modexp_l1024_input_t maths_modexp_l1024; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_odd_l768_input_t maths_modinv_odd_l768; + /** Modular exponentiation for numbers less than 1536-bits */ + icp_qat_fw_maths_modexp_l1536_input_t maths_modexp_l1536; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_odd_l1024_input_t maths_modinv_odd_l1024; + /** Modular exponentiation for numbers less than 2048-bit */ + icp_qat_fw_maths_modexp_l2048_input_t maths_modexp_l2048; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_odd_l1536_input_t maths_modinv_odd_l1536; + /** Modular exponentiation for numbers less than 2560-bits */ + icp_qat_fw_maths_modexp_l2560_input_t maths_modexp_l2560; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_odd_l2048_input_t maths_modinv_odd_l2048; + /** Modular exponentiation for numbers less than 3072-bits */ + icp_qat_fw_maths_modexp_l3072_input_t maths_modexp_l3072; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_odd_l3072_input_t maths_modinv_odd_l3072; + /** Modular exponentiation for numbers less than 3584-bits */ + icp_qat_fw_maths_modexp_l3584_input_t maths_modexp_l3584; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_odd_l4096_input_t maths_modinv_odd_l4096; + /** Modular exponentiation for numbers less than 4096-bit */ + icp_qat_fw_maths_modexp_l4096_input_t maths_modexp_l4096; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_even_l128_input_t maths_modinv_even_l128; + /** Modular exponentiation for numbers up to 8192 bits */ + icp_qat_fw_maths_modexp_l8192_input_t maths_modexp_l8192; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_even_l192_input_t maths_modinv_even_l192; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_odd_l128_input_t maths_modinv_odd_l128; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_even_l256_input_t maths_modinv_even_l256; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_odd_l192_input_t maths_modinv_odd_l192; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_even_l384_input_t maths_modinv_even_l384; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_odd_l256_input_t maths_modinv_odd_l256; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_even_l512_input_t maths_modinv_even_l512; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_odd_l384_input_t maths_modinv_odd_l384; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_even_l768_input_t maths_modinv_even_l768; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_odd_l512_input_t maths_modinv_odd_l512; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_even_l1024_input_t maths_modinv_even_l1024; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_odd_l768_input_t maths_modinv_odd_l768; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_even_l1536_input_t maths_modinv_even_l1536; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_odd_l1024_input_t maths_modinv_odd_l1024; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_even_l2048_input_t maths_modinv_even_l2048; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_odd_l1536_input_t maths_modinv_odd_l1536; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_even_l3072_input_t maths_modinv_even_l3072; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_odd_l2048_input_t maths_modinv_odd_l2048; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_even_l4096_input_t maths_modinv_even_l4096; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_odd_l3072_input_t maths_modinv_odd_l3072; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t mmp_dsa_gen_p_1024_160; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_odd_l4096_input_t maths_modinv_odd_l4096; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_1024_input_t mmp_dsa_gen_g_1024; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_odd_l8192_input_t maths_modinv_odd_l8192; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_1024_input_t mmp_dsa_gen_y_1024; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_even_l128_input_t maths_modinv_even_l128; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t mmp_dsa_sign_r_1024_160; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_even_l192_input_t maths_modinv_even_l192; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_160_input_t mmp_dsa_sign_s_160; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_even_l256_input_t maths_modinv_even_l256; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t mmp_dsa_sign_r_s_1024_160; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_even_l384_input_t maths_modinv_even_l384; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_1024_160_input_t mmp_dsa_verify_1024_160; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_even_l512_input_t maths_modinv_even_l512; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t mmp_dsa_gen_p_2048_224; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_even_l768_input_t maths_modinv_even_l768; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_2048_input_t mmp_dsa_gen_y_2048; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_even_l1024_input_t maths_modinv_even_l1024; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t mmp_dsa_sign_r_2048_224; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_even_l1536_input_t maths_modinv_even_l1536; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_224_input_t mmp_dsa_sign_s_224; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_even_l2048_input_t maths_modinv_even_l2048; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t mmp_dsa_sign_r_s_2048_224; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_even_l3072_input_t maths_modinv_even_l3072; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_224_input_t mmp_dsa_verify_2048_224; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_even_l4096_input_t maths_modinv_even_l4096; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t mmp_dsa_gen_p_2048_256; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_even_l8192_input_t maths_modinv_even_l8192; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_2048_input_t mmp_dsa_gen_g_2048; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t mmp_dsa_gen_p_1024_160; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t mmp_dsa_sign_r_2048_256; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_1024_input_t mmp_dsa_gen_g_1024; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_256_input_t mmp_dsa_sign_s_256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_1024_input_t mmp_dsa_gen_y_1024; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t mmp_dsa_sign_r_s_2048_256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t mmp_dsa_sign_r_1024_160; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_256_input_t mmp_dsa_verify_2048_256; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_160_input_t mmp_dsa_sign_s_160; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t mmp_dsa_gen_p_3072_256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t mmp_dsa_sign_r_s_1024_160; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_3072_input_t mmp_dsa_gen_g_3072; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_1024_160_input_t mmp_dsa_verify_1024_160; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_3072_input_t mmp_dsa_gen_y_3072; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t mmp_dsa_gen_p_2048_224; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t mmp_dsa_sign_r_3072_256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_2048_input_t mmp_dsa_gen_y_2048; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t mmp_dsa_sign_r_s_3072_256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t mmp_dsa_sign_r_2048_224; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_3072_256_input_t mmp_dsa_verify_3072_256; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_224_input_t mmp_dsa_sign_s_224; - /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t - mmp_ecdsa_sign_rs_gf2_l256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t mmp_dsa_sign_r_s_2048_224; - /** ECDSA Sign R for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t mmp_ecdsa_sign_r_gf2_l256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_224_input_t mmp_dsa_verify_2048_224; - /** ECDSA Sign S for curves with n < 2^256 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t mmp_ecdsa_sign_s_gf2_l256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t mmp_dsa_gen_p_2048_256; - /** ECDSA Verify for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t mmp_ecdsa_verify_gf2_l256; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_2048_input_t mmp_dsa_gen_g_2048; - /** ECDSA Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t - mmp_ecdsa_sign_rs_gf2_l512; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t mmp_dsa_sign_r_2048_256; - /** ECDSA GF2 Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t mmp_ecdsa_sign_r_gf2_l512; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_256_input_t mmp_dsa_sign_s_256; - /** ECDSA GF2 Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t mmp_ecdsa_sign_s_gf2_l512; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t mmp_dsa_sign_r_s_2048_256; - /** ECDSA GF2 Verify */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t mmp_ecdsa_verify_gf2_l512; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_256_input_t mmp_dsa_verify_2048_256; - /** ECDSA GF2 Sign RS for curves B-571/K-571 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t mmp_ecdsa_sign_rs_gf2_571; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t mmp_dsa_gen_p_3072_256; - /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t mmp_ecdsa_sign_s_gf2_571; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_3072_input_t mmp_dsa_gen_g_3072; - /** ECDSA GF2 Sign R for degree 571 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t mmp_ecdsa_sign_r_gf2_571; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_3072_input_t mmp_dsa_gen_y_3072; - /** ECDSA GF2 Verify for degree 571 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t mmp_ecdsa_verify_gf2_571; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t mmp_dsa_sign_r_3072_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l256_input_t - maths_point_multiplication_gf2_l256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t mmp_dsa_sign_r_s_3072_256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l256_input_t - maths_point_verify_gf2_l256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_3072_256_input_t mmp_dsa_verify_3072_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l512_input_t - maths_point_multiplication_gf2_l512; + /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t mmp_ecdsa_sign_rs_gf2_l256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l512_input_t - maths_point_verify_gf2_l512; + /** ECDSA Sign R for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t mmp_ecdsa_sign_r_gf2_l256; - /** ECC GF2 Point Multiplication for curves B-571/K-571 */ - icp_qat_fw_maths_point_multiplication_gf2_571_input_t - maths_point_multiplication_gf2_571; + /** ECDSA Sign S for curves with n < 2^256 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t mmp_ecdsa_sign_s_gf2_l256; - /** ECC GF2 Point Verification for degree 571 */ - icp_qat_fw_maths_point_verify_gf2_571_input_t - maths_point_verify_gf2_571; + /** ECDSA Verify for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t mmp_ecdsa_verify_gf2_l256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t mmp_ecdsa_sign_r_gfp_l256; + /** ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t mmp_ecdsa_sign_rs_gf2_l512; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t mmp_ecdsa_sign_s_gfp_l256; + /** ECDSA GF2 Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t mmp_ecdsa_sign_r_gf2_l512; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t - mmp_ecdsa_sign_rs_gfp_l256; + /** ECDSA GF2 Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t mmp_ecdsa_sign_s_gf2_l512; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t mmp_ecdsa_verify_gfp_l256; + /** ECDSA GF2 Verify */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t mmp_ecdsa_verify_gf2_l512; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t mmp_ecdsa_sign_r_gfp_l512; + /** ECDSA GF2 Sign RS for curves B-571/K-571 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t mmp_ecdsa_sign_rs_gf2_571; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t mmp_ecdsa_sign_s_gfp_l512; + /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t mmp_ecdsa_sign_s_gf2_571; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t - mmp_ecdsa_sign_rs_gfp_l512; + /** ECDSA GF2 Sign R for degree 571 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t mmp_ecdsa_sign_r_gf2_571; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t mmp_ecdsa_verify_gfp_l512; + /** ECDSA GF2 Verify for degree 571 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t mmp_ecdsa_verify_gf2_571; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t mmp_ecdsa_sign_r_gfp_521; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l256_input_t maths_point_multiplication_gf2_l256; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t mmp_ecdsa_sign_s_gfp_521; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l256_input_t maths_point_verify_gf2_l256; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t mmp_ecdsa_sign_rs_gfp_521; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l512_input_t maths_point_multiplication_gf2_l512; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t mmp_ecdsa_verify_gfp_521; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l512_input_t maths_point_verify_gf2_l512; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l256_input_t - maths_point_multiplication_gfp_l256; + /** ECC GF2 Point Multiplication for curves B-571/K-571 */ + icp_qat_fw_maths_point_multiplication_gf2_571_input_t maths_point_multiplication_gf2_571; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_l256_input_t - maths_point_verify_gfp_l256; + /** ECC GF2 Point Verification for degree 571 */ + icp_qat_fw_maths_point_verify_gf2_571_input_t maths_point_verify_gf2_571; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l512_input_t - maths_point_multiplication_gfp_l512; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t mmp_ecdsa_sign_r_gfp_l256; - /** ECC GFP Partial Point */ - icp_qat_fw_maths_point_verify_gfp_l512_input_t - maths_point_verify_gfp_l512; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t mmp_ecdsa_sign_s_gfp_l256; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_521_input_t - maths_point_multiplication_gfp_521; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t mmp_ecdsa_sign_rs_gfp_l256; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_521_input_t - maths_point_verify_gfp_521; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t mmp_ecdsa_verify_gfp_l256; - /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified - * in RFC7748 */ - icp_qat_fw_point_multiplication_c25519_input_t - point_multiplication_c25519; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t mmp_ecdsa_sign_r_gfp_l512; - /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified - * in RFC7748 */ - icp_qat_fw_generator_multiplication_c25519_input_t - generator_multiplication_c25519; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t mmp_ecdsa_sign_s_gfp_l512; - /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed25519_input_t - point_multiplication_ed25519; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t mmp_ecdsa_sign_rs_gfp_l512; - /** ECC edwards25519 Generator Point Multiplication [k]G, as specified - * in RFC8032 */ - icp_qat_fw_generator_multiplication_ed25519_input_t - generator_multiplication_ed25519; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t mmp_ecdsa_verify_gfp_l512; - /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in - * RFC7748 */ - icp_qat_fw_point_multiplication_c448_input_t point_multiplication_c448; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t mmp_ecdsa_sign_r_gfp_521; - /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in - * RFC7748 */ - icp_qat_fw_generator_multiplication_c448_input_t - generator_multiplication_c448; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t mmp_ecdsa_sign_s_gfp_521; - /** ECC edwards448 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed448_input_t - point_multiplication_ed448; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t mmp_ecdsa_sign_rs_gfp_521; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t mmp_ecdsa_verify_gfp_521; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l256_input_t maths_point_multiplication_gfp_l256; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_l256_input_t maths_point_verify_gfp_l256; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l512_input_t maths_point_multiplication_gfp_l512; + + /** ECC GFP Partial Point */ + icp_qat_fw_maths_point_verify_gfp_l512_input_t maths_point_verify_gfp_l512; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_521_input_t maths_point_multiplication_gfp_521; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_521_input_t maths_point_verify_gfp_521; + + /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 */ + icp_qat_fw_point_multiplication_c25519_input_t point_multiplication_c25519; + + /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 */ + icp_qat_fw_generator_multiplication_c25519_input_t generator_multiplication_c25519; + + /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_point_multiplication_ed25519_input_t point_multiplication_ed25519; + + /** ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 */ + icp_qat_fw_generator_multiplication_ed25519_input_t generator_multiplication_ed25519; + + /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 */ + icp_qat_fw_point_multiplication_c448_input_t point_multiplication_c448; + + /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 */ + icp_qat_fw_generator_multiplication_c448_input_t generator_multiplication_c448; + + /** ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_point_multiplication_ed448_input_t point_multiplication_ed448; + + /** ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_generator_multiplication_ed448_input_t generator_multiplication_ed448; + + /** ECC P521 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_t mmp_kpt_ecdsa_sign_rs_p521; + + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_t mmp_kpt_ecdsa_sign_rs_p384; + + /** ECC KPT P256 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_t mmp_kpt_ecdsa_sign_rs_p256; + + /** KPT RSA 512 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_512_input_t mmp_kpt_rsa_dp1_512; + + /** KPT RSA 1024 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_t mmp_kpt_rsa_dp1_1024; + + /** KPT RSA 1536 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_t mmp_kpt_rsa_dp1_1536; + + /** KPT RSA 2048 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_t mmp_kpt_rsa_dp1_2048; + + /** KPT RSA 3072 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_t mmp_kpt_rsa_dp1_3072; + + /** KPT RSA 4096 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_t mmp_kpt_rsa_dp1_4096; + + /** KPT RSA 8192 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_t mmp_kpt_rsa_dp1_8192; + + /** RSA 512 decryption second form */ + icp_qat_fw_mmp_kpt_rsa_dp2_512_input_t mmp_kpt_rsa_dp2_512; + + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_t mmp_kpt_rsa_dp2_1024; + + /** KPT RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_t mmp_kpt_rsa_dp2_1536; + + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_t mmp_kpt_rsa_dp2_2048; + + /** */ + icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_t mmp_kpt_rsa_dp2_3072; + + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_t mmp_kpt_rsa_dp2_4096; + + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_t mmp_kpt_rsa_dp2_8192; - /** ECC edwards448 Generator Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_generator_multiplication_ed448_input_t - generator_multiplication_ed448; } icp_qat_fw_mmp_input_param_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p384_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]P (6 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]P (6 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p384_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]G (6 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]G (6 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p256_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]P (4 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]P (4 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p256_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p256_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]G (4 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p256_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC SM2 point multiply [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECSM2_GENERATOR_MULTIPLICATION. + */ +typedef struct icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s +{ + uint64_t xd; /**< xD = affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yd; /**< yD = affine coordinate Y of point [k]G (4 qwords)*/ +} icp_qat_fw_mmp_ecsm2_generator_multiplication_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Initialisation sequence , * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_INIT. */ -typedef struct icp_qat_fw_mmp_init_output_s { - uint64_t zz; /**< 1'd quadword (1 qwords)*/ +typedef struct icp_qat_fw_mmp_init_output_s +{ + uint64_t zz; /**< 1'd quadword (1 qwords)*/ } icp_qat_fw_mmp_init_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_768. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_768. */ -typedef struct icp_qat_fw_mmp_dh_g2_768_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_768_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 qwords)*/ } icp_qat_fw_mmp_dh_g2_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_768. + * Output parameter list for Diffie-Hellman Modular exponentiation for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_768. */ -typedef struct icp_qat_fw_mmp_dh_768_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_768_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 qwords)*/ } icp_qat_fw_mmp_dh_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_1024. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_1024. */ -typedef struct icp_qat_fw_mmp_dh_g2_1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ } icp_qat_fw_mmp_dh_g2_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_1024. + * Output parameter list for Diffie-Hellman Modular exponentiation for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_1024. */ -typedef struct icp_qat_fw_mmp_dh_1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ } icp_qat_fw_mmp_dh_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_1536. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_1536. */ -typedef struct icp_qat_fw_mmp_dh_g2_1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ } icp_qat_fw_mmp_dh_g2_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_1536. + * Output parameter list for Diffie-Hellman Modular exponentiation for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_1536. */ -typedef struct icp_qat_fw_mmp_dh_1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ } icp_qat_fw_mmp_dh_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_2048. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_2048. */ -typedef struct icp_qat_fw_mmp_dh_g2_2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ } icp_qat_fw_mmp_dh_g2_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_2048. + * Output parameter list for Diffie-Hellman Modular exponentiation for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_2048. */ -typedef struct icp_qat_fw_mmp_dh_2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ } icp_qat_fw_mmp_dh_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_3072. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_3072. */ -typedef struct icp_qat_fw_mmp_dh_g2_3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ } icp_qat_fw_mmp_dh_g2_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_3072. + * Output parameter list for Diffie-Hellman Modular exponentiation for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_3072. */ -typedef struct icp_qat_fw_mmp_dh_3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ } icp_qat_fw_mmp_dh_3072_output_t; -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_4096. - */ -typedef struct icp_qat_fw_mmp_dh_g2_4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ -} icp_qat_fw_mmp_dh_g2_4096_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_4096. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_4096. */ -typedef struct icp_qat_fw_mmp_dh_4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ +} icp_qat_fw_mmp_dh_g2_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Diffie-Hellman Modular exponentiation for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_4096. + */ +typedef struct icp_qat_fw_mmp_dh_4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ } icp_qat_fw_mmp_dh_4096_output_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for RSA 512 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_512. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers , to be used when icp_qat_fw_pke_response_s::functionalityId + * is #PKE_DH_G2_8192. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_512_output_s { - uint64_t n; /**< RSA key (8 qwords)*/ - uint64_t d; /**< RSA private key (first form) (8 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_mmp_dh_g2_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Diffie-Hellman Modular exponentiation for + * 8192-bit numbers , to be used when icp_qat_fw_pke_response_s::functionalityId + * is #PKE_DH_8192. + */ +typedef struct icp_qat_fw_mmp_dh_8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_mmp_dh_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 512 key generation first form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_512. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_512_output_s +{ + uint64_t n; /**< RSA key (8 qwords)*/ + uint64_t d; /**< RSA private key (first form) (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_512. */ -typedef struct icp_qat_fw_mmp_rsa_kp2_512_output_s { - uint64_t n; /**< RSA key (8 qwords)*/ - uint64_t d; /**< RSA private key (second form) (8 qwords)*/ - uint64_t dp; /**< RSA private key (second form) (4 qwords)*/ - uint64_t dq; /**< RSA private key (second form) (4 qwords)*/ - uint64_t qinv; /**< RSA private key (second form) (4 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp2_512_output_s +{ + uint64_t n; /**< RSA key (8 qwords)*/ + uint64_t d; /**< RSA private key (second form) (8 qwords)*/ + uint64_t dp; /**< RSA private key (second form) (4 qwords)*/ + uint64_t dq; /**< RSA private key (second form) (4 qwords)*/ + uint64_t qinv; /**< RSA private key (second form) (4 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_512. */ -typedef struct icp_qat_fw_mmp_rsa_ep_512_output_s { - uint64_t c; /**< cipher text representative, < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_512_output_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ } icp_qat_fw_mmp_rsa_ep_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_512_output_s { - uint64_t m; /**< message representative, < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_512_output_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_512_output_s { - uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_512_output_s +{ + uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1024_output_s { - uint64_t n; /**< RSA key (16 qwords)*/ - uint64_t d; /**< RSA private key (first form) (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_1024_output_s +{ + uint64_t n; /**< RSA key (16 qwords)*/ + uint64_t d; /**< RSA private key (first form) (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_1024. */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1024_output_s { - uint64_t n; /**< RSA key (16 qwords)*/ - uint64_t d; /**< RSA private key (second form) (16 qwords)*/ - uint64_t dp; /**< RSA private key (second form) (8 qwords)*/ - uint64_t dq; /**< RSA private key (second form) (8 qwords)*/ - uint64_t qinv; /**< RSA private key (second form) (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp2_1024_output_s +{ + uint64_t n; /**< RSA key (16 qwords)*/ + uint64_t d; /**< RSA private key (second form) (16 qwords)*/ + uint64_t dp; /**< RSA private key (second form) (8 qwords)*/ + uint64_t dq; /**< RSA private key (second form) (8 qwords)*/ + uint64_t qinv; /**< RSA private key (second form) (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_1024. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1024_output_s { - uint64_t c; /**< cipher text representative, < n (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1024_output_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1024_output_s { - uint64_t m; /**< message representative, < n (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1024_output_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1024_output_t; + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1024 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1024_output_s +{ + uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1536 key generation first form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_1536_output_s +{ + uint64_t n; /**< RSA key (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1536 key generation second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1536_output_s +{ + uint64_t n; /**< RSA key (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ + uint64_t dp; /**< RSA private key (12 qwords)*/ + uint64_t dq; /**< RSA private key (12 qwords)*/ + uint64_t qinv; /**< RSA private key (12 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1536 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_1536_output_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1536 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_1536_output_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1536 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1536_output_s +{ + uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 key generation first form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_2048_output_s +{ + uint64_t n; /**< RSA key (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 key generation second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_2048_output_s +{ + uint64_t n; /**< RSA key (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ + uint64_t dp; /**< RSA private key (16 qwords)*/ + uint64_t dq; /**< RSA private key (16 qwords)*/ + uint64_t qinv; /**< RSA private key (16 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_2048_output_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_2048_output_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_2048_output_s +{ + uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 3072 key generation first form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_3072_output_s +{ + uint64_t n; /**< RSA key (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 3072 key generation second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_3072_output_s +{ + uint64_t n; /**< RSA key (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ + uint64_t dp; /**< RSA private key (24 qwords)*/ + uint64_t dq; /**< RSA private key (24 qwords)*/ + uint64_t qinv; /**< RSA private key (24 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 3072 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_3072_output_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 3072 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_3072_output_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 3072 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_3072_output_s +{ + uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 key generation first form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_4096_output_s +{ + uint64_t n; /**< RSA key (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ +} icp_qat_fw_mmp_rsa_kp1_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 key generation second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_4096_output_s +{ + uint64_t n; /**< RSA key (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ + uint64_t dp; /**< RSA private key (32 qwords)*/ + uint64_t dq; /**< RSA private key (32 qwords)*/ + uint64_t qinv; /**< RSA private key (32 qwords)*/ +} icp_qat_fw_mmp_rsa_kp2_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_4096_output_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_4096_output_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_4096_output_s +{ + uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_RSA_EP_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_8192_output_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_8192_output_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_RSA_DP2_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_8192_output_s +{ + uint64_t m; /**< message representative, < (p*q) (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 192-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_192. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_192_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_192_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 256-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_256. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_256_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 384-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_384. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_384_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_384_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_512. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_768. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_768_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_1024. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_1024_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_1536. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_1536_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_2048. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_2048_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_3072. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_3072_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_4096. + */ +typedef struct icp_qat_fw_mmp_gcd_pt_4096_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_gcd_pt_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_160. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_160_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_512. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for <e; 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_L512. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_768. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_768_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_1024. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_1024_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_1536. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_1536_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_2048. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_2048_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_3072. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_3072_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Fermat primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_4096. + */ +typedef struct icp_qat_fw_mmp_fermat_pt_4096_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_fermat_pt_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_160. + */ +typedef struct icp_qat_fw_mmp_mr_pt_160_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_512. + */ +typedef struct icp_qat_fw_mmp_mr_pt_512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_768. + */ +typedef struct icp_qat_fw_mmp_mr_pt_768_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_1024. + */ +typedef struct icp_qat_fw_mmp_mr_pt_1024_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_1536. + */ +typedef struct icp_qat_fw_mmp_mr_pt_1536_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_2048. + */ +typedef struct icp_qat_fw_mmp_mr_pt_2048_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_3072. + */ +typedef struct icp_qat_fw_mmp_mr_pt_3072_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_4096. + */ +typedef struct icp_qat_fw_mmp_mr_pt_4096_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_L512. + */ +typedef struct icp_qat_fw_mmp_mr_pt_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_mr_pt_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_160. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_160_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_512. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_768. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_768_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_1024. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_1024_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_1536. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_1536_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_2048. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_2048_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_3072. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_3072_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_4096. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_4096_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_4096_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Lucas primality test for L512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_L512. + */ +typedef struct icp_qat_fw_mmp_lucas_pt_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_lucas_pt_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 512-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L512. + */ +typedef struct icp_qat_fw_maths_modexp_l512_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (8 qwords)*/ +} icp_qat_fw_maths_modexp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 1024-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L1024. + */ +typedef struct icp_qat_fw_maths_modexp_l1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ +} icp_qat_fw_maths_modexp_l1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 1536-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L1536. + */ +typedef struct icp_qat_fw_maths_modexp_l1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ +} icp_qat_fw_maths_modexp_l1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 2048-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L2048. + */ +typedef struct icp_qat_fw_maths_modexp_l2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ +} icp_qat_fw_maths_modexp_l2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 2560-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L2560. + */ +typedef struct icp_qat_fw_maths_modexp_l2560_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (40 qwords)*/ +} icp_qat_fw_maths_modexp_l2560_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 3072-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L3072. + */ +typedef struct icp_qat_fw_maths_modexp_l3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ +} icp_qat_fw_maths_modexp_l3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 3584-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L3584. + */ +typedef struct icp_qat_fw_maths_modexp_l3584_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (56 qwords)*/ +} icp_qat_fw_maths_modexp_l3584_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers less than 4096-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L4096. + */ +typedef struct icp_qat_fw_maths_modexp_l4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ +} icp_qat_fw_maths_modexp_l4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers up to 8192 + * bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODEXP_L8192. + */ +typedef struct icp_qat_fw_maths_modexp_l8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_maths_modexp_l8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less + * than 128 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_ODD_L128. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l128_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (2 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l128_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (3 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l192_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L256. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l256_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (4 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L384. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l384_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (6 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l384_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L512. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l512_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (8 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L768. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l768_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (12 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L1024. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l1024_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (16 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L1536. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l1536_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (24 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L2048. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l2048_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (32 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L3072. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l3072_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (48 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L4096. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l4096_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (64 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_ODD_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l8192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (128 + qwords)*/ +} icp_qat_fw_maths_modinv_odd_l8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less + * than 128 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_EVEN_L128. + */ +typedef struct icp_qat_fw_maths_modinv_even_l128_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (2 qwords)*/ +} icp_qat_fw_maths_modinv_even_l128_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (3 qwords)*/ +} icp_qat_fw_maths_modinv_even_l192_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L256. + */ +typedef struct icp_qat_fw_maths_modinv_even_l256_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (4 qwords)*/ +} icp_qat_fw_maths_modinv_even_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L384. + */ +typedef struct icp_qat_fw_maths_modinv_even_l384_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (6 qwords)*/ +} icp_qat_fw_maths_modinv_even_l384_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L512. + */ +typedef struct icp_qat_fw_maths_modinv_even_l512_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (8 qwords)*/ +} icp_qat_fw_maths_modinv_even_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L768. + */ +typedef struct icp_qat_fw_maths_modinv_even_l768_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (12 qwords)*/ +} icp_qat_fw_maths_modinv_even_l768_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L1024. + */ +typedef struct icp_qat_fw_maths_modinv_even_l1024_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (16 qwords)*/ +} icp_qat_fw_maths_modinv_even_l1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L1536. + */ +typedef struct icp_qat_fw_maths_modinv_even_l1536_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (24 qwords)*/ +} icp_qat_fw_maths_modinv_even_l1536_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L2048. + */ +typedef struct icp_qat_fw_maths_modinv_even_l2048_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (32 qwords)*/ +} icp_qat_fw_maths_modinv_even_l2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L3072. + */ +typedef struct icp_qat_fw_maths_modinv_even_l3072_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (48 qwords)*/ +} icp_qat_fw_maths_modinv_even_l3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L4096. + */ +typedef struct icp_qat_fw_maths_modinv_even_l4096_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (64 qwords)*/ +} icp_qat_fw_maths_modinv_even_l4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_EVEN_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l8192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (128 + qwords)*/ +} icp_qat_fw_maths_modinv_even_l8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (16 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_1024. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_output_s +{ + uint64_t g; /**< DSA parameter (16 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_1024. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_output_s +{ + uint64_t y; /**< DSA parameter (16 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_1024_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_output_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_160_output_s +{ + uint64_t s; /**< s DSA 160-bits signature (3 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_dsa_verify_1024_160_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_2048. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_output_s +{ + uint64_t y; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_output_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_224_output_s +{ + uint64_t s; /**< s DSA 224-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_224_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_dsa_verify_2048_224_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_2048. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_output_s +{ + uint64_t g; /**< DSA parameter (32 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_2048_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_256_output_s +{ + uint64_t s; /**< s DSA 256-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_s_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_dsa_verify_2048_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA parameter generation P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (48 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_3072. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_output_s +{ + uint64_t g; /**< DSA parameter (48 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_g_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA key generation Y , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_3072. + */ +typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_output_s +{ + uint64_t y; /**< DSA parameter (48 qwords)*/ +} icp_qat_fw_mmp_dsa_gen_y_3072_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Sign R S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ +} icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for DSA Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_dsa_verify_3072_256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ + uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA Sign S for curves with n < 2^256 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_s +{ + uint64_t r; /**< (8 qwords)*/ + uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s > 0 and < n (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_s +{ + uint64_t r; /**< (9 qwords)*/ + uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s > 0 and < n (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Sign R for degree 571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GF2 Verify for degree 571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (< degree(q)) (4 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (< degree(q)) (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l256_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gf2_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (< q) (8 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (< q) (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gf2_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GF2 Point Multiplication for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (degree < degree(q)) (9 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (degree < degree(q)) (9 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GF2 Point Verification for degree 571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_571_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gf2_571_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_s +{ + uint64_t r; /**< ECDSA signature (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_s +{ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_s +{ + uint64_t r; /**< ECDSA signature (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_s +{ + uint64_t s; /**< ECDSA signature s (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_s +{ + uint64_t r; /**< ECDSA signature r (8 qwords)*/ + uint64_t s; /**< ECDSA signature s (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_s +{ + uint64_t r; /**< ECDSA signature (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_s +{ + uint64_t s; /**< ECDSA signature s (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_s +{ + uint64_t r; /**< ECDSA signature r (9 qwords)*/ + uint64_t s; /**< ECDSA signature s (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_s +{ + /* no output parameters */ +} icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (4 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l256_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gfp_l256_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (8 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Partial Point , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l512_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gfp_l512_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (9 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (9 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_521_output_s +{ + /* no output parameters */ +} icp_qat_fw_maths_point_verify_gfp_521_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_C25519. + */ +typedef struct icp_qat_fw_point_multiplication_c25519_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]P (4 qwords)*/ +} icp_qat_fw_point_multiplication_c25519_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_C25519. + */ +typedef struct icp_qat_fw_generator_multiplication_c25519_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]G (4 qwords)*/ +} icp_qat_fw_generator_multiplication_c25519_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_point_multiplication_ed25519_output_s +{ + uint64_t xr; /**< xR = Twisted Edwards affine coordinate X of point [k]P (4 qwords)*/ + uint64_t yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]P (4 qwords)*/ +} icp_qat_fw_point_multiplication_ed25519_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_generator_multiplication_ed25519_output_s +{ + uint64_t xr; /**< xR = Twisted Edwards affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]G (4 qwords)*/ +} icp_qat_fw_generator_multiplication_ed25519_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_C448. + */ +typedef struct icp_qat_fw_point_multiplication_c448_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]P (8 qwords)*/ +} icp_qat_fw_point_multiplication_c448_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_C448. + */ +typedef struct icp_qat_fw_generator_multiplication_c448_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]G (8 qwords)*/ +} icp_qat_fw_generator_multiplication_c448_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_ED448. + */ +typedef struct icp_qat_fw_point_multiplication_ed448_output_s +{ + uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]P (8 qwords)*/ + uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]P (8 qwords)*/ +} icp_qat_fw_point_multiplication_ed448_output_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_ED448. + */ +typedef struct icp_qat_fw_generator_multiplication_ed448_output_s +{ + uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]G (8 qwords)*/ + uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]G (8 qwords)*/ +} icp_qat_fw_generator_multiplication_ed448_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P521 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P521. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC KPT P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 512 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_512_output_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_512_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 1024 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 1536 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 2048 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 3072 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 4096 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 512 decryption second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_512_output_s +{ + uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_512_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_1024. + * #PKE_KPT_RSA_DP2_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1024_output_s { - uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_1024_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_s +{ + uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for RSA 1536 key generation first form , + * Output parameter list for KPT RSA 1536 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_1536. + * #PKE_KPT_RSA_DP2_1536. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1536_output_s { - uint64_t n; /**< RSA key (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 1536 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1536_output_s { - uint64_t n; /**< RSA key (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ - uint64_t dp; /**< RSA private key (12 qwords)*/ - uint64_t dq; /**< RSA private key (12 qwords)*/ - uint64_t qinv; /**< RSA private key (12 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 1536 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_1536_output_s { - uint64_t c; /**< cipher text representative, < n (24 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 1536 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1536_output_s { - uint64_t m; /**< message representative, < n (24 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 1536 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1536_output_s { - uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 2048 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_2048_output_s { - uint64_t n; /**< RSA key (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 2048 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_2048_output_s { - uint64_t n; /**< RSA key (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ - uint64_t dp; /**< RSA private key (16 qwords)*/ - uint64_t dq; /**< RSA private key (16 qwords)*/ - uint64_t qinv; /**< RSA private key (16 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 2048 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_2048_output_s { - uint64_t c; /**< cipher text representative, < n (32 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 2048 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_2048_output_s { - uint64_t m; /**< message representative, < n (32 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_2048_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_s +{ + uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_t; /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_2048. + * #PKE_KPT_RSA_DP2_2048. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_2048_output_s { - uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_2048_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_s +{ + uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for RSA 3072 key generation first form , + * Output parameter list for , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_3072. + * #PKE_KPT_RSA_DP2_3072. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_3072_output_s { - uint64_t n; /**< RSA key (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 3072 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_3072_output_s { - uint64_t n; /**< RSA key (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ - uint64_t dp; /**< RSA private key (24 qwords)*/ - uint64_t dq; /**< RSA private key (24 qwords)*/ - uint64_t qinv; /**< RSA private key (24 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 3072 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_3072_output_s { - uint64_t c; /**< cipher text representative, < n (48 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 3072 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_3072_output_s { - uint64_t m; /**< message representative, < n (48 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 3072 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_3072_output_s { - uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 4096 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_4096_output_s { - uint64_t n; /**< RSA key (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ -} icp_qat_fw_mmp_rsa_kp1_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 4096 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_4096_output_s { - uint64_t n; /**< RSA key (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ - uint64_t dp; /**< RSA private key (32 qwords)*/ - uint64_t dq; /**< RSA private key (32 qwords)*/ - uint64_t qinv; /**< RSA private key (32 qwords)*/ -} icp_qat_fw_mmp_rsa_kp2_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 4096 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_ep_4096_output_s { - uint64_t c; /**< cipher text representative, < n (64 qwords)*/ -} icp_qat_fw_mmp_rsa_ep_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for RSA 4096 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_dp1_4096_output_s { - uint64_t m; /**< message representative, < n (64 qwords)*/ -} icp_qat_fw_mmp_rsa_dp1_4096_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_s +{ + uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_t; /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_4096. + * #PKE_KPT_RSA_DP2_4096. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_4096_output_s { - uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ -} icp_qat_fw_mmp_rsa_dp2_4096_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_s +{ + uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for GCD primality test for 192-bit numbers , + * Output parameter list for RSA 8192 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_192. + * #PKE_KPT_RSA_DP2_8192. */ -typedef struct icp_qat_fw_mmp_gcd_pt_192_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_192_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 256-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_256. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_256_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 384-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_384. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_384_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_384_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_512. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_768. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_768_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_1024. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_1024_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_1536. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_1536_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_2048. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_2048_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_3072. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_3072_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for GCD primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_4096. - */ -typedef struct icp_qat_fw_mmp_gcd_pt_4096_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_gcd_pt_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_160. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_160_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_512. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for <e; 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_L512. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_l512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_768. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_768_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_1024. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_1024_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_1536. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_1536_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_2048. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_2048_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_3072. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_3072_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Fermat primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_4096. - */ -typedef struct icp_qat_fw_mmp_fermat_pt_4096_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_fermat_pt_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 160-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_160. - */ -typedef struct icp_qat_fw_mmp_mr_pt_160_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_512. - */ -typedef struct icp_qat_fw_mmp_mr_pt_512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 768-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_768. - */ -typedef struct icp_qat_fw_mmp_mr_pt_768_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 1024-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_1024. - */ -typedef struct icp_qat_fw_mmp_mr_pt_1024_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 1536-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_1536. - */ -typedef struct icp_qat_fw_mmp_mr_pt_1536_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 2048-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_2048. - */ -typedef struct icp_qat_fw_mmp_mr_pt_2048_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 3072-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_3072. - */ -typedef struct icp_qat_fw_mmp_mr_pt_3072_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 4096-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_4096. - */ -typedef struct icp_qat_fw_mmp_mr_pt_4096_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Miller-Rabin primality test for 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_L512. - */ -typedef struct icp_qat_fw_mmp_mr_pt_l512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_mr_pt_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_160. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_160_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_512. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_768. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_768_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_1024. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_1024_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_1536. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_1536_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_2048. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_2048_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_3072. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_3072_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_4096. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_4096_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Lucas primality test for L512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_L512. - */ -typedef struct icp_qat_fw_mmp_lucas_pt_l512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_lucas_pt_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 512-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L512. - */ -typedef struct icp_qat_fw_maths_modexp_l512_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (8 - qwords)*/ -} icp_qat_fw_maths_modexp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 1024-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L1024. - */ -typedef struct icp_qat_fw_maths_modexp_l1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ -} icp_qat_fw_maths_modexp_l1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 1536-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L1536. - */ -typedef struct icp_qat_fw_maths_modexp_l1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ -} icp_qat_fw_maths_modexp_l1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 2048-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L2048. - */ -typedef struct icp_qat_fw_maths_modexp_l2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ -} icp_qat_fw_maths_modexp_l2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 2560-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L2560. - */ -typedef struct icp_qat_fw_maths_modexp_l2560_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (40 - qwords)*/ -} icp_qat_fw_maths_modexp_l2560_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 3072-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L3072. - */ -typedef struct icp_qat_fw_maths_modexp_l3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ -} icp_qat_fw_maths_modexp_l3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 3584-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L3584. - */ -typedef struct icp_qat_fw_maths_modexp_l3584_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (56 - qwords)*/ -} icp_qat_fw_maths_modexp_l3584_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 4096-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L4096. - */ -typedef struct icp_qat_fw_maths_modexp_l4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ -} icp_qat_fw_maths_modexp_l4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L128. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l128_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (2 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l128_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L192. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l192_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (3 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l192_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L256. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l256_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (4 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L384. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l384_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (6 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l384_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L512. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l512_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (8 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L768. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l768_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (12 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L1024. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l1024_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (16 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L1536. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l1536_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (24 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L2048. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l2048_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (32 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L3072. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l3072_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (48 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L4096. - */ -typedef struct icp_qat_fw_maths_modinv_odd_l4096_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (64 - qwords)*/ -} icp_qat_fw_maths_modinv_odd_l4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L128. - */ -typedef struct icp_qat_fw_maths_modinv_even_l128_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (2 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l128_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L192. - */ -typedef struct icp_qat_fw_maths_modinv_even_l192_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (3 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l192_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L256. - */ -typedef struct icp_qat_fw_maths_modinv_even_l256_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (4 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L384. - */ -typedef struct icp_qat_fw_maths_modinv_even_l384_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (6 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l384_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L512. - */ -typedef struct icp_qat_fw_maths_modinv_even_l512_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (8 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L768. - */ -typedef struct icp_qat_fw_maths_modinv_even_l768_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (12 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l768_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L1024. - */ -typedef struct icp_qat_fw_maths_modinv_even_l1024_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (16 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L1536. - */ -typedef struct icp_qat_fw_maths_modinv_even_l1536_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (24 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l1536_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L2048. - */ -typedef struct icp_qat_fw_maths_modinv_even_l2048_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (32 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L3072. - */ -typedef struct icp_qat_fw_maths_modinv_even_l3072_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (48 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L4096. - */ -typedef struct icp_qat_fw_maths_modinv_even_l4096_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (64 - qwords)*/ -} icp_qat_fw_maths_modinv_even_l4096_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_output_s { - uint64_t p; /**< candidate for DSA parameter p (16 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_1024. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_output_s { - uint64_t g; /**< DSA parameter (16 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_1024. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_output_s { - uint64_t y; /**< DSA parameter (16 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_1024_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_output_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_160_output_s { - uint64_t s; /**< s DSA 160-bits signature (3 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_dsa_verify_1024_160_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_output_s { - uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_2048. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_output_s { - uint64_t y; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_output_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_224_output_s { - uint64_t s; /**< s DSA 224-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_224_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_dsa_verify_2048_224_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_output_s { - uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_2048. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_output_s { - uint64_t g; /**< DSA parameter (32 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_2048_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_256_output_s { - uint64_t s; /**< s DSA 256-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_s_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_dsa_verify_2048_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_output_s { - uint64_t p; /**< candidate for DSA parameter p (48 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_3072. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_output_s { - uint64_t g; /**< DSA parameter (48 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_g_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_3072. - */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_output_s { - uint64_t y; /**< DSA parameter (48 qwords)*/ -} icp_qat_fw_mmp_dsa_gen_y_3072_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ -} icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_dsa_verify_3072_256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ - uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA Sign S for curves with n < 2^256 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_s { - uint64_t r; /**< (8 qwords)*/ - uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s - > 0 and < n (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_s { - uint64_t r; /**< (9 qwords)*/ - uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s - > 0 and < n (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Sign R for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GF2 Verify for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_output_s { - uint64_t xk; /**< x coordinate of resultant point (< degree(q)) (4 - qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (< degree(q)) (4 - qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l256_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gf2_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_output_s { - uint64_t xk; /**< x coordinate of resultant point (< q) (8 qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (< q) (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l512_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gf2_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GF2 Point Multiplication for curves - * B-571/K-571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_output_s { - uint64_t xk; /**< x coordinate of resultant point (degree < - degree(q)) (9 qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (degree < - degree(q)) (9 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GF2 Point Verification for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_571_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gf2_571_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_s { - uint64_t r; /**< ECDSA signature (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_s { - uint64_t s; /**< ECDSA signature s (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_s { - uint64_t r; /**< ECDSA signature r (4 qwords)*/ - uint64_t s; /**< ECDSA signature s (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_s { - uint64_t r; /**< ECDSA signature (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_s { - uint64_t s; /**< ECDSA signature s (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_s { - uint64_t r; /**< ECDSA signature r (8 qwords)*/ - uint64_t s; /**< ECDSA signature s (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_s { - uint64_t r; /**< ECDSA signature (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_s { - uint64_t s; /**< ECDSA signature s (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_s { - uint64_t r; /**< ECDSA signature r (9 qwords)*/ - uint64_t s; /**< ECDSA signature s (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_s { - /* no output parameters */ -} icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (4 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (4 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l256_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gfp_l256_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (8 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Partial Point , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l512_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gfp_l512_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (9 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (9 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_521_output_s { - /* no output parameters */ -} icp_qat_fw_maths_point_verify_gfp_521_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC curve25519 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_C25519. - */ -typedef struct icp_qat_fw_point_multiplication_c25519_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]P (4 - qwords)*/ -} icp_qat_fw_point_multiplication_c25519_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC curve25519 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C25519. - */ -typedef struct icp_qat_fw_generator_multiplication_c25519_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]G (4 - qwords)*/ -} icp_qat_fw_generator_multiplication_c25519_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC edwards25519 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_point_multiplication_ed25519_output_s { - uint64_t - xr; /**< xR = Twisted Edwards affine coordinate X of point [k]P (4 - qwords)*/ - uint64_t - yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]P (4 - qwords)*/ -} icp_qat_fw_point_multiplication_ed25519_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC edwards25519 Generator Point Multiplication - * [k]G, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_generator_multiplication_ed25519_output_s { - uint64_t - xr; /**< xR = Twisted Edwards affine coordinate X of point [k]G (4 - qwords)*/ - uint64_t - yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]G (4 - qwords)*/ -} icp_qat_fw_generator_multiplication_ed25519_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC curve448 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_C448. - */ -typedef struct icp_qat_fw_point_multiplication_c448_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]P (8 - qwords)*/ -} icp_qat_fw_point_multiplication_c448_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC curve448 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C448. - */ -typedef struct icp_qat_fw_generator_multiplication_c448_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]G (8 - qwords)*/ -} icp_qat_fw_generator_multiplication_c448_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC edwards448 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_ED448. - */ -typedef struct icp_qat_fw_point_multiplication_ed448_output_s { - uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]P (8 - qwords)*/ - uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]P (8 - qwords)*/ -} icp_qat_fw_point_multiplication_ed448_output_t; - -/** - * @ingroup icp_qat_fw_mmp - * @brief - * Output parameter list for ECC edwards448 Generator Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED448. - */ -typedef struct icp_qat_fw_generator_multiplication_ed448_output_s { - uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]G (8 - qwords)*/ - uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]G (8 - qwords)*/ -} icp_qat_fw_generator_multiplication_ed448_output_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_s +{ + uint64_t m; /**< message representative, < (p*q) (128 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_t; /** * @ingroup icp_qat_fw_mmp * @brief * MMP output parameters */ -typedef union icp_qat_fw_mmp_output_param_u { - /** Generic parameter structure : All members of this wrapper structure - * are pointers to large integers. - */ - uint64_t flat_array[ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX]; +typedef union icp_qat_fw_mmp_output_param_u +{ + /** Generic parameter structure : All members of this wrapper structure + * are pointers to large integers. + */ + uint64_t flat_array[ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX]; - /** Initialisation sequence */ - icp_qat_fw_mmp_init_output_t mmp_init; + /** ECC P384 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p384_output_t + mmp_ec_point_multiplication_p384; - /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ - icp_qat_fw_mmp_dh_g2_768_output_t mmp_dh_g2_768; + /** ECC P384 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p384_output_t + mmp_ec_generator_multiplication_p384; - /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ - icp_qat_fw_mmp_dh_768_output_t mmp_dh_768; + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_t mmp_ecdsa_sign_rs_p384; - /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ - icp_qat_fw_mmp_dh_g2_1024_output_t mmp_dh_g2_1024; + /** ECC P256 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p256_output_t + mmp_ec_point_multiplication_p256; - /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ - icp_qat_fw_mmp_dh_1024_output_t mmp_dh_1024; + /** ECC P256 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p256_output_t + mmp_ec_generator_multiplication_p256; - /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ - icp_qat_fw_mmp_dh_g2_1536_output_t mmp_dh_g2_1536; + /** ECC P256 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_t mmp_ecdsa_sign_rs_p256; - /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ - icp_qat_fw_mmp_dh_1536_output_t mmp_dh_1536; + /** ECC SM2 point multiply [k]G */ + icp_qat_fw_mmp_ecsm2_generator_multiplication_output_t + mmp_ecsm2_generator_multiplication; - /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ - icp_qat_fw_mmp_dh_g2_2048_output_t mmp_dh_g2_2048; + /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified in + * RFC7748 */ + icp_qat_fw_point_multiplication_c25519_output_t point_multiplication_c25519; - /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ - icp_qat_fw_mmp_dh_2048_output_t mmp_dh_2048; + /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified in + * RFC7748 */ + icp_qat_fw_generator_multiplication_c25519_output_t + generator_multiplication_c25519; - /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ - icp_qat_fw_mmp_dh_g2_3072_output_t mmp_dh_g2_3072; + /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in + * RFC8032 */ + icp_qat_fw_point_multiplication_ed25519_output_t + point_multiplication_ed25519; - /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ - icp_qat_fw_mmp_dh_3072_output_t mmp_dh_3072; + /** ECC edwards25519 Generator Point Multiplication [k]G, as specified in + * RFC8032 */ + icp_qat_fw_generator_multiplication_ed25519_output_t + generator_multiplication_ed25519; - /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ - icp_qat_fw_mmp_dh_g2_4096_output_t mmp_dh_g2_4096; + /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in + * RFC7748 */ + icp_qat_fw_point_multiplication_c448_output_t point_multiplication_c448; - /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ - icp_qat_fw_mmp_dh_4096_output_t mmp_dh_4096; + /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in + * RFC7748 */ + icp_qat_fw_generator_multiplication_c448_output_t + generator_multiplication_c448; - /** RSA 512 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_512_output_t mmp_rsa_kp1_512; + /** ECC edwards448 Variable Point Multiplication [k]P, as specified in + * RFC8032 */ + icp_qat_fw_point_multiplication_ed448_output_t point_multiplication_ed448; - /** RSA 512 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_512_output_t mmp_rsa_kp2_512; + /** ECC edwards448 Generator Point Multiplication [k]G, as specified in + * RFC8032 */ + icp_qat_fw_generator_multiplication_ed448_output_t + generator_multiplication_ed448; - /** RSA 512 Encryption */ - icp_qat_fw_mmp_rsa_ep_512_output_t mmp_rsa_ep_512; + /** Initialisation sequence */ + icp_qat_fw_mmp_init_output_t mmp_init; - /** RSA 512 Decryption */ - icp_qat_fw_mmp_rsa_dp1_512_output_t mmp_rsa_dp1_512; + /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ + icp_qat_fw_mmp_dh_g2_768_output_t mmp_dh_g2_768; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_512_output_t mmp_rsa_dp2_512; + /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ + icp_qat_fw_mmp_dh_768_output_t mmp_dh_768; - /** RSA 1024 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1024_output_t mmp_rsa_kp1_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ + icp_qat_fw_mmp_dh_g2_1024_output_t mmp_dh_g2_1024; - /** RSA 1024 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1024_output_t mmp_rsa_kp2_1024; + /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ + icp_qat_fw_mmp_dh_1024_output_t mmp_dh_1024; - /** RSA 1024 Encryption */ - icp_qat_fw_mmp_rsa_ep_1024_output_t mmp_rsa_ep_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ + icp_qat_fw_mmp_dh_g2_1536_output_t mmp_dh_g2_1536; - /** RSA 1024 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1024_output_t mmp_rsa_dp1_1024; + /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ + icp_qat_fw_mmp_dh_1536_output_t mmp_dh_1536; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1024_output_t mmp_rsa_dp2_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ + icp_qat_fw_mmp_dh_g2_2048_output_t mmp_dh_g2_2048; - /** RSA 1536 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1536_output_t mmp_rsa_kp1_1536; + /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ + icp_qat_fw_mmp_dh_2048_output_t mmp_dh_2048; - /** RSA 1536 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1536_output_t mmp_rsa_kp2_1536; + /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ + icp_qat_fw_mmp_dh_g2_3072_output_t mmp_dh_g2_3072; - /** RSA 1536 Encryption */ - icp_qat_fw_mmp_rsa_ep_1536_output_t mmp_rsa_ep_1536; + /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ + icp_qat_fw_mmp_dh_3072_output_t mmp_dh_3072; - /** RSA 1536 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1536_output_t mmp_rsa_dp1_1536; + /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ + icp_qat_fw_mmp_dh_g2_4096_output_t mmp_dh_g2_4096; - /** RSA 1536 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1536_output_t mmp_rsa_dp2_1536; + /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ + icp_qat_fw_mmp_dh_4096_output_t mmp_dh_4096; - /** RSA 2048 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_2048_output_t mmp_rsa_kp1_2048; + /** Diffie-Hellman Modular exponentiation base 2 for 8192-bit numbers */ + icp_qat_fw_mmp_dh_g2_8192_output_t mmp_dh_g2_8192; - /** RSA 2048 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_2048_output_t mmp_rsa_kp2_2048; + /** Diffie-Hellman Modular exponentiation for 8192-bit numbers */ + icp_qat_fw_mmp_dh_8192_output_t mmp_dh_8192; - /** RSA 2048 Encryption */ - icp_qat_fw_mmp_rsa_ep_2048_output_t mmp_rsa_ep_2048; + /** RSA 512 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_512_output_t mmp_rsa_kp1_512; - /** RSA 2048 Decryption */ - icp_qat_fw_mmp_rsa_dp1_2048_output_t mmp_rsa_dp1_2048; + /** RSA 512 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_512_output_t mmp_rsa_kp2_512; - /** RSA 2048 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_2048_output_t mmp_rsa_dp2_2048; + /** RSA 512 Encryption */ + icp_qat_fw_mmp_rsa_ep_512_output_t mmp_rsa_ep_512; - /** RSA 3072 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_3072_output_t mmp_rsa_kp1_3072; + /** RSA 512 Decryption */ + icp_qat_fw_mmp_rsa_dp1_512_output_t mmp_rsa_dp1_512; - /** RSA 3072 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_3072_output_t mmp_rsa_kp2_3072; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_512_output_t mmp_rsa_dp2_512; - /** RSA 3072 Encryption */ - icp_qat_fw_mmp_rsa_ep_3072_output_t mmp_rsa_ep_3072; + /** RSA 1024 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1024_output_t mmp_rsa_kp1_1024; - /** RSA 3072 Decryption */ - icp_qat_fw_mmp_rsa_dp1_3072_output_t mmp_rsa_dp1_3072; + /** RSA 1024 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1024_output_t mmp_rsa_kp2_1024; - /** RSA 3072 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_3072_output_t mmp_rsa_dp2_3072; + /** RSA 1024 Encryption */ + icp_qat_fw_mmp_rsa_ep_1024_output_t mmp_rsa_ep_1024; - /** RSA 4096 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_4096_output_t mmp_rsa_kp1_4096; + /** RSA 1024 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1024_output_t mmp_rsa_dp1_1024; - /** RSA 4096 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_4096_output_t mmp_rsa_kp2_4096; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1024_output_t mmp_rsa_dp2_1024; - /** RSA 4096 Encryption */ - icp_qat_fw_mmp_rsa_ep_4096_output_t mmp_rsa_ep_4096; + /** RSA 1536 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1536_output_t mmp_rsa_kp1_1536; - /** RSA 4096 Decryption */ - icp_qat_fw_mmp_rsa_dp1_4096_output_t mmp_rsa_dp1_4096; + /** RSA 1536 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1536_output_t mmp_rsa_kp2_1536; - /** RSA 4096 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_4096_output_t mmp_rsa_dp2_4096; + /** RSA 1536 Encryption */ + icp_qat_fw_mmp_rsa_ep_1536_output_t mmp_rsa_ep_1536; - /** GCD primality test for 192-bit numbers */ - icp_qat_fw_mmp_gcd_pt_192_output_t mmp_gcd_pt_192; + /** RSA 1536 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1536_output_t mmp_rsa_dp1_1536; - /** GCD primality test for 256-bit numbers */ - icp_qat_fw_mmp_gcd_pt_256_output_t mmp_gcd_pt_256; + /** RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1536_output_t mmp_rsa_dp2_1536; - /** GCD primality test for 384-bit numbers */ - icp_qat_fw_mmp_gcd_pt_384_output_t mmp_gcd_pt_384; + /** RSA 2048 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_2048_output_t mmp_rsa_kp1_2048; - /** GCD primality test for 512-bit numbers */ - icp_qat_fw_mmp_gcd_pt_512_output_t mmp_gcd_pt_512; + /** RSA 2048 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_2048_output_t mmp_rsa_kp2_2048; - /** GCD primality test for 768-bit numbers */ - icp_qat_fw_mmp_gcd_pt_768_output_t mmp_gcd_pt_768; + /** RSA 2048 Encryption */ + icp_qat_fw_mmp_rsa_ep_2048_output_t mmp_rsa_ep_2048; - /** GCD primality test for 1024-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1024_output_t mmp_gcd_pt_1024; + /** RSA 2048 Decryption */ + icp_qat_fw_mmp_rsa_dp1_2048_output_t mmp_rsa_dp1_2048; - /** GCD primality test for 1536-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1536_output_t mmp_gcd_pt_1536; + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_2048_output_t mmp_rsa_dp2_2048; - /** GCD primality test for 2048-bit numbers */ - icp_qat_fw_mmp_gcd_pt_2048_output_t mmp_gcd_pt_2048; + /** RSA 3072 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_3072_output_t mmp_rsa_kp1_3072; - /** GCD primality test for 3072-bit numbers */ - icp_qat_fw_mmp_gcd_pt_3072_output_t mmp_gcd_pt_3072; + /** RSA 3072 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_3072_output_t mmp_rsa_kp2_3072; - /** GCD primality test for 4096-bit numbers */ - icp_qat_fw_mmp_gcd_pt_4096_output_t mmp_gcd_pt_4096; + /** RSA 3072 Encryption */ + icp_qat_fw_mmp_rsa_ep_3072_output_t mmp_rsa_ep_3072; - /** Fermat primality test for 160-bit numbers */ - icp_qat_fw_mmp_fermat_pt_160_output_t mmp_fermat_pt_160; + /** RSA 3072 Decryption */ + icp_qat_fw_mmp_rsa_dp1_3072_output_t mmp_rsa_dp1_3072; - /** Fermat primality test for 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_512_output_t mmp_fermat_pt_512; + /** RSA 3072 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_3072_output_t mmp_rsa_dp2_3072; - /** Fermat primality test for <e; 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_l512_output_t mmp_fermat_pt_l512; + /** RSA 4096 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_4096_output_t mmp_rsa_kp1_4096; - /** Fermat primality test for 768-bit numbers */ - icp_qat_fw_mmp_fermat_pt_768_output_t mmp_fermat_pt_768; + /** RSA 4096 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_4096_output_t mmp_rsa_kp2_4096; - /** Fermat primality test for 1024-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1024_output_t mmp_fermat_pt_1024; + /** RSA 4096 Encryption */ + icp_qat_fw_mmp_rsa_ep_4096_output_t mmp_rsa_ep_4096; - /** Fermat primality test for 1536-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1536_output_t mmp_fermat_pt_1536; + /** RSA 4096 Decryption */ + icp_qat_fw_mmp_rsa_dp1_4096_output_t mmp_rsa_dp1_4096; - /** Fermat primality test for 2048-bit numbers */ - icp_qat_fw_mmp_fermat_pt_2048_output_t mmp_fermat_pt_2048; + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_4096_output_t mmp_rsa_dp2_4096; - /** Fermat primality test for 3072-bit numbers */ - icp_qat_fw_mmp_fermat_pt_3072_output_t mmp_fermat_pt_3072; + /** RSA 8192 Encryption */ + icp_qat_fw_mmp_rsa_ep_8192_output_t mmp_rsa_ep_8192; - /** Fermat primality test for 4096-bit numbers */ - icp_qat_fw_mmp_fermat_pt_4096_output_t mmp_fermat_pt_4096; + /** RSA 8192 Decryption */ + icp_qat_fw_mmp_rsa_dp1_8192_output_t mmp_rsa_dp1_8192; - /** Miller-Rabin primality test for 160-bit numbers */ - icp_qat_fw_mmp_mr_pt_160_output_t mmp_mr_pt_160; + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_8192_output_t mmp_rsa_dp2_8192; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_512_output_t mmp_mr_pt_512; + /** GCD primality test for 192-bit numbers */ + icp_qat_fw_mmp_gcd_pt_192_output_t mmp_gcd_pt_192; - /** Miller-Rabin primality test for 768-bit numbers */ - icp_qat_fw_mmp_mr_pt_768_output_t mmp_mr_pt_768; + /** GCD primality test for 256-bit numbers */ + icp_qat_fw_mmp_gcd_pt_256_output_t mmp_gcd_pt_256; - /** Miller-Rabin primality test for 1024-bit numbers */ - icp_qat_fw_mmp_mr_pt_1024_output_t mmp_mr_pt_1024; + /** GCD primality test for 384-bit numbers */ + icp_qat_fw_mmp_gcd_pt_384_output_t mmp_gcd_pt_384; - /** Miller-Rabin primality test for 1536-bit numbers */ - icp_qat_fw_mmp_mr_pt_1536_output_t mmp_mr_pt_1536; + /** GCD primality test for 512-bit numbers */ + icp_qat_fw_mmp_gcd_pt_512_output_t mmp_gcd_pt_512; - /** Miller-Rabin primality test for 2048-bit numbers */ - icp_qat_fw_mmp_mr_pt_2048_output_t mmp_mr_pt_2048; + /** GCD primality test for 768-bit numbers */ + icp_qat_fw_mmp_gcd_pt_768_output_t mmp_gcd_pt_768; - /** Miller-Rabin primality test for 3072-bit numbers */ - icp_qat_fw_mmp_mr_pt_3072_output_t mmp_mr_pt_3072; + /** GCD primality test for 1024-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1024_output_t mmp_gcd_pt_1024; - /** Miller-Rabin primality test for 4096-bit numbers */ - icp_qat_fw_mmp_mr_pt_4096_output_t mmp_mr_pt_4096; + /** GCD primality test for 1536-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1536_output_t mmp_gcd_pt_1536; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_l512_output_t mmp_mr_pt_l512; + /** GCD primality test for 2048-bit numbers */ + icp_qat_fw_mmp_gcd_pt_2048_output_t mmp_gcd_pt_2048; - /** Lucas primality test for 160-bit numbers */ - icp_qat_fw_mmp_lucas_pt_160_output_t mmp_lucas_pt_160; + /** GCD primality test for 3072-bit numbers */ + icp_qat_fw_mmp_gcd_pt_3072_output_t mmp_gcd_pt_3072; - /** Lucas primality test for 512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_512_output_t mmp_lucas_pt_512; + /** GCD primality test for 4096-bit numbers */ + icp_qat_fw_mmp_gcd_pt_4096_output_t mmp_gcd_pt_4096; - /** Lucas primality test for 768-bit numbers */ - icp_qat_fw_mmp_lucas_pt_768_output_t mmp_lucas_pt_768; + /** Fermat primality test for 160-bit numbers */ + icp_qat_fw_mmp_fermat_pt_160_output_t mmp_fermat_pt_160; - /** Lucas primality test for 1024-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1024_output_t mmp_lucas_pt_1024; + /** Fermat primality test for 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_512_output_t mmp_fermat_pt_512; - /** Lucas primality test for 1536-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1536_output_t mmp_lucas_pt_1536; + /** Fermat primality test for <e; 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_l512_output_t mmp_fermat_pt_l512; - /** Lucas primality test for 2048-bit numbers */ - icp_qat_fw_mmp_lucas_pt_2048_output_t mmp_lucas_pt_2048; + /** Fermat primality test for 768-bit numbers */ + icp_qat_fw_mmp_fermat_pt_768_output_t mmp_fermat_pt_768; - /** Lucas primality test for 3072-bit numbers */ - icp_qat_fw_mmp_lucas_pt_3072_output_t mmp_lucas_pt_3072; + /** Fermat primality test for 1024-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1024_output_t mmp_fermat_pt_1024; - /** Lucas primality test for 4096-bit numbers */ - icp_qat_fw_mmp_lucas_pt_4096_output_t mmp_lucas_pt_4096; + /** Fermat primality test for 1536-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1536_output_t mmp_fermat_pt_1536; - /** Lucas primality test for L512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_l512_output_t mmp_lucas_pt_l512; + /** Fermat primality test for 2048-bit numbers */ + icp_qat_fw_mmp_fermat_pt_2048_output_t mmp_fermat_pt_2048; - /** Modular exponentiation for numbers less than 512-bits */ - icp_qat_fw_maths_modexp_l512_output_t maths_modexp_l512; + /** Fermat primality test for 3072-bit numbers */ + icp_qat_fw_mmp_fermat_pt_3072_output_t mmp_fermat_pt_3072; - /** Modular exponentiation for numbers less than 1024-bit */ - icp_qat_fw_maths_modexp_l1024_output_t maths_modexp_l1024; + /** Fermat primality test for 4096-bit numbers */ + icp_qat_fw_mmp_fermat_pt_4096_output_t mmp_fermat_pt_4096; - /** Modular exponentiation for numbers less than 1536-bits */ - icp_qat_fw_maths_modexp_l1536_output_t maths_modexp_l1536; + /** Miller-Rabin primality test for 160-bit numbers */ + icp_qat_fw_mmp_mr_pt_160_output_t mmp_mr_pt_160; - /** Modular exponentiation for numbers less than 2048-bit */ - icp_qat_fw_maths_modexp_l2048_output_t maths_modexp_l2048; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_512_output_t mmp_mr_pt_512; - /** Modular exponentiation for numbers less than 2560-bits */ - icp_qat_fw_maths_modexp_l2560_output_t maths_modexp_l2560; + /** Miller-Rabin primality test for 768-bit numbers */ + icp_qat_fw_mmp_mr_pt_768_output_t mmp_mr_pt_768; - /** Modular exponentiation for numbers less than 3072-bits */ - icp_qat_fw_maths_modexp_l3072_output_t maths_modexp_l3072; + /** Miller-Rabin primality test for 1024-bit numbers */ + icp_qat_fw_mmp_mr_pt_1024_output_t mmp_mr_pt_1024; - /** Modular exponentiation for numbers less than 3584-bits */ - icp_qat_fw_maths_modexp_l3584_output_t maths_modexp_l3584; + /** Miller-Rabin primality test for 1536-bit numbers */ + icp_qat_fw_mmp_mr_pt_1536_output_t mmp_mr_pt_1536; - /** Modular exponentiation for numbers less than 4096-bit */ - icp_qat_fw_maths_modexp_l4096_output_t maths_modexp_l4096; + /** Miller-Rabin primality test for 2048-bit numbers */ + icp_qat_fw_mmp_mr_pt_2048_output_t mmp_mr_pt_2048; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_odd_l128_output_t maths_modinv_odd_l128; + /** Miller-Rabin primality test for 3072-bit numbers */ + icp_qat_fw_mmp_mr_pt_3072_output_t mmp_mr_pt_3072; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_odd_l192_output_t maths_modinv_odd_l192; + /** Miller-Rabin primality test for 4096-bit numbers */ + icp_qat_fw_mmp_mr_pt_4096_output_t mmp_mr_pt_4096; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_odd_l256_output_t maths_modinv_odd_l256; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_l512_output_t mmp_mr_pt_l512; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_odd_l384_output_t maths_modinv_odd_l384; + /** Lucas primality test for 160-bit numbers */ + icp_qat_fw_mmp_lucas_pt_160_output_t mmp_lucas_pt_160; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_odd_l512_output_t maths_modinv_odd_l512; + /** Lucas primality test for 512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_512_output_t mmp_lucas_pt_512; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_odd_l768_output_t maths_modinv_odd_l768; + /** Lucas primality test for 768-bit numbers */ + icp_qat_fw_mmp_lucas_pt_768_output_t mmp_lucas_pt_768; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_odd_l1024_output_t maths_modinv_odd_l1024; + /** Lucas primality test for 1024-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1024_output_t mmp_lucas_pt_1024; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_odd_l1536_output_t maths_modinv_odd_l1536; + /** Lucas primality test for 1536-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1536_output_t mmp_lucas_pt_1536; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_odd_l2048_output_t maths_modinv_odd_l2048; + /** Lucas primality test for 2048-bit numbers */ + icp_qat_fw_mmp_lucas_pt_2048_output_t mmp_lucas_pt_2048; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_odd_l3072_output_t maths_modinv_odd_l3072; + /** Lucas primality test for 3072-bit numbers */ + icp_qat_fw_mmp_lucas_pt_3072_output_t mmp_lucas_pt_3072; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_odd_l4096_output_t maths_modinv_odd_l4096; + /** Lucas primality test for 4096-bit numbers */ + icp_qat_fw_mmp_lucas_pt_4096_output_t mmp_lucas_pt_4096; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_even_l128_output_t maths_modinv_even_l128; + /** Lucas primality test for L512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_l512_output_t mmp_lucas_pt_l512; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_even_l192_output_t maths_modinv_even_l192; + /** Modular exponentiation for numbers less than 512-bits */ + icp_qat_fw_maths_modexp_l512_output_t maths_modexp_l512; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_even_l256_output_t maths_modinv_even_l256; + /** Modular exponentiation for numbers less than 1024-bit */ + icp_qat_fw_maths_modexp_l1024_output_t maths_modexp_l1024; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_even_l384_output_t maths_modinv_even_l384; + /** Modular exponentiation for numbers less than 1536-bits */ + icp_qat_fw_maths_modexp_l1536_output_t maths_modexp_l1536; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_even_l512_output_t maths_modinv_even_l512; + /** Modular exponentiation for numbers less than 2048-bit */ + icp_qat_fw_maths_modexp_l2048_output_t maths_modexp_l2048; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_even_l768_output_t maths_modinv_even_l768; + /** Modular exponentiation for numbers less than 2560-bits */ + icp_qat_fw_maths_modexp_l2560_output_t maths_modexp_l2560; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_even_l1024_output_t maths_modinv_even_l1024; + /** Modular exponentiation for numbers less than 3072-bits */ + icp_qat_fw_maths_modexp_l3072_output_t maths_modexp_l3072; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_even_l1536_output_t maths_modinv_even_l1536; + /** Modular exponentiation for numbers less than 3584-bits */ + icp_qat_fw_maths_modexp_l3584_output_t maths_modexp_l3584; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_even_l2048_output_t maths_modinv_even_l2048; + /** Modular exponentiation for numbers less than 4096-bit */ + icp_qat_fw_maths_modexp_l4096_output_t maths_modexp_l4096; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_even_l3072_output_t maths_modinv_even_l3072; + /** Modular exponentiation for numbers up to 8192 bits */ + icp_qat_fw_maths_modexp_l8192_output_t maths_modexp_l8192; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_even_l4096_output_t maths_modinv_even_l4096; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_odd_l128_output_t maths_modinv_odd_l128; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t mmp_dsa_gen_p_1024_160; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_odd_l192_output_t maths_modinv_odd_l192; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_1024_output_t mmp_dsa_gen_g_1024; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_odd_l256_output_t maths_modinv_odd_l256; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_1024_output_t mmp_dsa_gen_y_1024; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_odd_l384_output_t maths_modinv_odd_l384; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t mmp_dsa_sign_r_1024_160; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_odd_l512_output_t maths_modinv_odd_l512; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_160_output_t mmp_dsa_sign_s_160; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_odd_l768_output_t maths_modinv_odd_l768; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t mmp_dsa_sign_r_s_1024_160; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_odd_l1024_output_t maths_modinv_odd_l1024; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_1024_160_output_t mmp_dsa_verify_1024_160; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_odd_l1536_output_t maths_modinv_odd_l1536; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t mmp_dsa_gen_p_2048_224; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_odd_l2048_output_t maths_modinv_odd_l2048; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_2048_output_t mmp_dsa_gen_y_2048; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_odd_l3072_output_t maths_modinv_odd_l3072; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t mmp_dsa_sign_r_2048_224; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_odd_l4096_output_t maths_modinv_odd_l4096; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_224_output_t mmp_dsa_sign_s_224; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_odd_l8192_output_t maths_modinv_odd_l8192; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t mmp_dsa_sign_r_s_2048_224; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_even_l128_output_t maths_modinv_even_l128; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_224_output_t mmp_dsa_verify_2048_224; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_even_l192_output_t maths_modinv_even_l192; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t mmp_dsa_gen_p_2048_256; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_even_l256_output_t maths_modinv_even_l256; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_2048_output_t mmp_dsa_gen_g_2048; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_even_l384_output_t maths_modinv_even_l384; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t mmp_dsa_sign_r_2048_256; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_even_l512_output_t maths_modinv_even_l512; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_256_output_t mmp_dsa_sign_s_256; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_even_l768_output_t maths_modinv_even_l768; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t mmp_dsa_sign_r_s_2048_256; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_even_l1024_output_t maths_modinv_even_l1024; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_256_output_t mmp_dsa_verify_2048_256; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_even_l1536_output_t maths_modinv_even_l1536; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t mmp_dsa_gen_p_3072_256; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_even_l2048_output_t maths_modinv_even_l2048; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_3072_output_t mmp_dsa_gen_g_3072; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_even_l3072_output_t maths_modinv_even_l3072; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_3072_output_t mmp_dsa_gen_y_3072; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_even_l4096_output_t maths_modinv_even_l4096; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t mmp_dsa_sign_r_3072_256; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_even_l8192_output_t maths_modinv_even_l8192; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t mmp_dsa_sign_r_s_3072_256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t mmp_dsa_gen_p_1024_160; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_3072_256_output_t mmp_dsa_verify_3072_256; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_1024_output_t mmp_dsa_gen_g_1024; - /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t - mmp_ecdsa_sign_rs_gf2_l256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_1024_output_t mmp_dsa_gen_y_1024; - /** ECDSA Sign R for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t mmp_ecdsa_sign_r_gf2_l256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t mmp_dsa_sign_r_1024_160; - /** ECDSA Sign S for curves with n < 2^256 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t mmp_ecdsa_sign_s_gf2_l256; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_160_output_t mmp_dsa_sign_s_160; - /** ECDSA Verify for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t mmp_ecdsa_verify_gf2_l256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t mmp_dsa_sign_r_s_1024_160; - /** ECDSA Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t - mmp_ecdsa_sign_rs_gf2_l512; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_1024_160_output_t mmp_dsa_verify_1024_160; - /** ECDSA GF2 Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t mmp_ecdsa_sign_r_gf2_l512; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t mmp_dsa_gen_p_2048_224; - /** ECDSA GF2 Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t mmp_ecdsa_sign_s_gf2_l512; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_2048_output_t mmp_dsa_gen_y_2048; - /** ECDSA GF2 Verify */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t mmp_ecdsa_verify_gf2_l512; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t mmp_dsa_sign_r_2048_224; - /** ECDSA GF2 Sign RS for curves B-571/K-571 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t mmp_ecdsa_sign_rs_gf2_571; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_224_output_t mmp_dsa_sign_s_224; - /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t mmp_ecdsa_sign_s_gf2_571; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t mmp_dsa_sign_r_s_2048_224; - /** ECDSA GF2 Sign R for degree 571 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t mmp_ecdsa_sign_r_gf2_571; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_224_output_t mmp_dsa_verify_2048_224; - /** ECDSA GF2 Verify for degree 571 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t mmp_ecdsa_verify_gf2_571; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t mmp_dsa_gen_p_2048_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l256_output_t - maths_point_multiplication_gf2_l256; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_2048_output_t mmp_dsa_gen_g_2048; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l256_output_t - maths_point_verify_gf2_l256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t mmp_dsa_sign_r_2048_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l512_output_t - maths_point_multiplication_gf2_l512; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_256_output_t mmp_dsa_sign_s_256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l512_output_t - maths_point_verify_gf2_l512; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t mmp_dsa_sign_r_s_2048_256; - /** ECC GF2 Point Multiplication for curves B-571/K-571 */ - icp_qat_fw_maths_point_multiplication_gf2_571_output_t - maths_point_multiplication_gf2_571; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_256_output_t mmp_dsa_verify_2048_256; - /** ECC GF2 Point Verification for degree 571 */ - icp_qat_fw_maths_point_verify_gf2_571_output_t - maths_point_verify_gf2_571; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t mmp_dsa_gen_p_3072_256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t mmp_ecdsa_sign_r_gfp_l256; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_3072_output_t mmp_dsa_gen_g_3072; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t mmp_ecdsa_sign_s_gfp_l256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_3072_output_t mmp_dsa_gen_y_3072; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t - mmp_ecdsa_sign_rs_gfp_l256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t mmp_dsa_sign_r_3072_256; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t mmp_ecdsa_verify_gfp_l256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t mmp_dsa_sign_r_s_3072_256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t mmp_ecdsa_sign_r_gfp_l512; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_3072_256_output_t mmp_dsa_verify_3072_256; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t mmp_ecdsa_sign_s_gfp_l512; + /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t mmp_ecdsa_sign_rs_gf2_l256; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t - mmp_ecdsa_sign_rs_gfp_l512; + /** ECDSA Sign R for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t mmp_ecdsa_sign_r_gf2_l256; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t mmp_ecdsa_verify_gfp_l512; + /** ECDSA Sign S for curves with n < 2^256 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t mmp_ecdsa_sign_s_gf2_l256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t mmp_ecdsa_sign_r_gfp_521; + /** ECDSA Verify for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t mmp_ecdsa_verify_gf2_l256; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t mmp_ecdsa_sign_s_gfp_521; + /** ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t mmp_ecdsa_sign_rs_gf2_l512; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t mmp_ecdsa_sign_rs_gfp_521; + /** ECDSA GF2 Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t mmp_ecdsa_sign_r_gf2_l512; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t mmp_ecdsa_verify_gfp_521; + /** ECDSA GF2 Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t mmp_ecdsa_sign_s_gf2_l512; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l256_output_t - maths_point_multiplication_gfp_l256; + /** ECDSA GF2 Verify */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t mmp_ecdsa_verify_gf2_l512; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_l256_output_t - maths_point_verify_gfp_l256; + /** ECDSA GF2 Sign RS for curves B-571/K-571 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t mmp_ecdsa_sign_rs_gf2_571; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l512_output_t - maths_point_multiplication_gfp_l512; + /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t mmp_ecdsa_sign_s_gf2_571; - /** ECC GFP Partial Point */ - icp_qat_fw_maths_point_verify_gfp_l512_output_t - maths_point_verify_gfp_l512; + /** ECDSA GF2 Sign R for degree 571 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t mmp_ecdsa_sign_r_gf2_571; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_521_output_t - maths_point_multiplication_gfp_521; + /** ECDSA GF2 Verify for degree 571 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t mmp_ecdsa_verify_gf2_571; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_521_output_t - maths_point_verify_gfp_521; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l256_output_t maths_point_multiplication_gf2_l256; - /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified - * in RFC7748 */ - icp_qat_fw_point_multiplication_c25519_output_t - point_multiplication_c25519; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l256_output_t maths_point_verify_gf2_l256; - /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified - * in RFC7748 */ - icp_qat_fw_generator_multiplication_c25519_output_t - generator_multiplication_c25519; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l512_output_t maths_point_multiplication_gf2_l512; - /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed25519_output_t - point_multiplication_ed25519; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l512_output_t maths_point_verify_gf2_l512; - /** ECC edwards25519 Generator Point Multiplication [k]G, as specified - * in RFC8032 */ - icp_qat_fw_generator_multiplication_ed25519_output_t - generator_multiplication_ed25519; + /** ECC GF2 Point Multiplication for curves B-571/K-571 */ + icp_qat_fw_maths_point_multiplication_gf2_571_output_t maths_point_multiplication_gf2_571; - /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in - * RFC7748 */ - icp_qat_fw_point_multiplication_c448_output_t point_multiplication_c448; + /** ECC GF2 Point Verification for degree 571 */ + icp_qat_fw_maths_point_verify_gf2_571_output_t maths_point_verify_gf2_571; - /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in - * RFC7748 */ - icp_qat_fw_generator_multiplication_c448_output_t - generator_multiplication_c448; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t mmp_ecdsa_sign_r_gfp_l256; - /** ECC edwards448 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed448_output_t - point_multiplication_ed448; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t mmp_ecdsa_sign_s_gfp_l256; + + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t mmp_ecdsa_sign_rs_gfp_l256; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t mmp_ecdsa_verify_gfp_l256; + + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t mmp_ecdsa_sign_r_gfp_l512; + + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t mmp_ecdsa_sign_s_gfp_l512; + + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t mmp_ecdsa_sign_rs_gfp_l512; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t mmp_ecdsa_verify_gfp_l512; + + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t mmp_ecdsa_sign_r_gfp_521; + + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t mmp_ecdsa_sign_s_gfp_521; + + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t mmp_ecdsa_sign_rs_gfp_521; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t mmp_ecdsa_verify_gfp_521; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l256_output_t maths_point_multiplication_gfp_l256; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_l256_output_t maths_point_verify_gfp_l256; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l512_output_t maths_point_multiplication_gfp_l512; + + /** ECC GFP Partial Point */ + icp_qat_fw_maths_point_verify_gfp_l512_output_t maths_point_verify_gfp_l512; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_521_output_t maths_point_multiplication_gfp_521; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_521_output_t maths_point_verify_gfp_521; + + /** ECC P521 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_t mmp_kpt_ecdsa_sign_rs_p521; + + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_t mmp_kpt_ecdsa_sign_rs_p384; + + /** ECC KPT P256 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_t mmp_kpt_ecdsa_sign_rs_p256; + + /** KPT RSA 512 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_512_output_t mmp_kpt_rsa_dp1_512; + + /** KPT RSA 1024 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_t mmp_kpt_rsa_dp1_1024; + + /** KPT RSA 1536 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_t mmp_kpt_rsa_dp1_1536; + + /** KPT RSA 2048 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_t mmp_kpt_rsa_dp1_2048; + + /** KPT RSA 3072 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_t mmp_kpt_rsa_dp1_3072; + + /** KPT RSA 4096 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_t mmp_kpt_rsa_dp1_4096; + + /** KPT RSA 8192 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_t mmp_kpt_rsa_dp1_8192; + + /** RSA 512 decryption second form */ + icp_qat_fw_mmp_kpt_rsa_dp2_512_output_t mmp_kpt_rsa_dp2_512; + + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_t mmp_kpt_rsa_dp2_1024; + + /** KPT RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_t mmp_kpt_rsa_dp2_1536; + + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_t mmp_kpt_rsa_dp2_2048; + + /** */ + icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_t mmp_kpt_rsa_dp2_3072; + + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_t mmp_kpt_rsa_dp2_4096; + + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_t mmp_kpt_rsa_dp2_8192; - /** ECC edwards448 Generator Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_generator_multiplication_ed448_output_t - generator_multiplication_ed448; } icp_qat_fw_mmp_output_param_t; + + #endif /* __ICP_QAT_FW_MMP__ */ + /* --- (Automatically generated (build v. 2.7), do not modify manually) --- */ /* --- end of file --- */ diff --git a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h index 9ccccc221453..dfda374e326c 100644 --- a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h +++ b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ + + +/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- */ + /** * @file icp_qat_fw_mmp_ids.h * @ingroup icp_qat_fw_mmp @@ -14,7 +18,159 @@ #ifndef __ICP_QAT_FW_MMP_IDS__ #define __ICP_QAT_FW_MMP_IDS__ -#define PKE_INIT 0x09061798 +#define PKE_ECSM2_GENERATOR_MULTIPLICATION 0x220f16ae +/**< Functionality ID for ECC SM2 point multiply [k]G + * @li 1 input parameters : @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s::xd xd @endlink @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s::yd yd @endlink + */ +#define PKE_ECSM2_POINT_MULTIPLICATION 0x211716ce +/**< Functionality ID for ECC SM2 point multiply [k]P + * @li 3 input parameters : @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::k k @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::x x @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::y y @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_output_s::xd xd @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_output_s::yd yd @endlink + */ +#define PKE_ECSM2_POINT_VERIFY 0x1b0716a6 +/**< Functionality ID for ECC SM2 point verify + * @li 2 input parameters : @link icp_qat_fw_mmp_ecsm2_point_verify_input_s::x x + * @endlink @link icp_qat_fw_mmp_ecsm2_point_verify_input_s::y y @endlink + * @li no output parameters + */ +#define PKE_ECSM2_SIGN_RS 0x222116fe +/**< Functionality ID for ECC SM2 Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_sign_rs_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecsm2_sign_rs_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecsm2_sign_rs_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_sign_rs_output_s::r r + * @endlink @link icp_qat_fw_mmp_ecsm2_sign_rs_output_s::s s @endlink + */ +#define PKE_ECSM2_VERIFY 0x29241743 +/**< Functionality ID for ECC SM2 Signature Verify + * @li 5 input parameters : @link icp_qat_fw_mmp_ecsm2_verify_input_s::e e + * @endlink @link icp_qat_fw_mmp_ecsm2_verify_input_s::r r @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::s s @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::yp yp @endlink + * @li no output parameters + */ +#define PKE_ECSM2_ENCRYPTION 0x25221720 +/**< Functionality ID for ECC SM2 encryption + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_encryption_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecsm2_encryption_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_encryption_input_s::yp yp @endlink + * @li 4 output parameters : @link icp_qat_fw_mmp_ecsm2_encryption_output_s::xc + * xc @endlink @link icp_qat_fw_mmp_ecsm2_encryption_output_s::yc yc @endlink + * @link icp_qat_fw_mmp_ecsm2_encryption_output_s::xpb xpb @endlink @link + * icp_qat_fw_mmp_ecsm2_encryption_output_s::ypb ypb @endlink + */ +#define PKE_ECSM2_DECRYPTION 0x201716e6 +/**< Functionality ID for ECC SM2 decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_decryption_input_s::d d + * @endlink @link icp_qat_fw_mmp_ecsm2_decryption_input_s::xpb xpb @endlink + * @link icp_qat_fw_mmp_ecsm2_decryption_input_s::ypb ypb @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_decryption_output_s::xd + * xd @endlink @link icp_qat_fw_mmp_ecsm2_decryption_output_s::yd yd @endlink + */ +#define PKE_ECSM2_KEYEX_P1 0x220f16be +/**< Functionality ID for ECC SM2 key exchange phase1 + * @li 1 input parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p1_input_s::k k + * @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p1_output_s::xd xd + * @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p1_output_s::yd yd @endlink + */ +#define PKE_ECSM2_KEYEX_P2 0x22361768 +/**< Functionality ID for ECC SM2 key exchange phase2 + * @li 7 input parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::r r + * @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::d d @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::x1 x1 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::x2 x2 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::y2 y2 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::yp yp @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p2_output_s::xus + * xus @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p2_output_s::yus yus @endlink + */ +#define POINT_MULTIPLICATION_C25519 0x0a0634c6 +/**< Functionality ID for ECC curve25519 Variable Point Multiplication [k]P(x), + * as specified in RFC7748 + * @li 2 input parameters : @link + * icp_qat_fw_point_multiplication_c25519_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_c25519_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_point_multiplication_c25519_output_s::xr xr @endlink + */ +#define GENERATOR_MULTIPLICATION_C25519 0x0a0634d6 +/**< Functionality ID for ECC curve25519 Generator Point Multiplication [k]G(x), + * as specified in RFC7748 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_c25519_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_generator_multiplication_c25519_output_s::xr xr @endlink + */ +#define POINT_MULTIPLICATION_ED25519 0x100b34e6 +/**< Functionality ID for ECC edwards25519 Variable Point Multiplication [k]P, + * as specified in RFC8032 + * @li 3 input parameters : @link + * icp_qat_fw_point_multiplication_ed25519_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_ed25519_input_s::yp yp @endlink @link + * icp_qat_fw_point_multiplication_ed25519_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_point_multiplication_ed25519_output_s::xr xr @endlink @link + * icp_qat_fw_point_multiplication_ed25519_output_s::yr yr @endlink + */ +#define GENERATOR_MULTIPLICATION_ED25519 0x100a34f6 +/**< Functionality ID for ECC edwards25519 Generator Point Multiplication [k]G, + * as specified in RFC8032 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_ed25519_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_generator_multiplication_ed25519_output_s::xr xr @endlink @link + * icp_qat_fw_generator_multiplication_ed25519_output_s::yr yr @endlink + */ +#define POINT_MULTIPLICATION_C448 0x0c063506 +/**< Functionality ID for ECC curve448 Variable Point Multiplication [k]P(x), as + * specified in RFC7748 + * @li 2 input parameters : @link + * icp_qat_fw_point_multiplication_c448_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_c448_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_point_multiplication_c448_output_s::xr xr @endlink + */ +#define GENERATOR_MULTIPLICATION_C448 0x0c063516 +/**< Functionality ID for ECC curve448 Generator Point Multiplication [k]G(x), + * as specified in RFC7748 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_c448_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_generator_multiplication_c448_output_s::xr xr @endlink + */ +#define POINT_MULTIPLICATION_ED448 0x1a0b3526 +/**< Functionality ID for ECC edwards448 Variable Point Multiplication [k]P, as + * specified in RFC8032 + * @li 3 input parameters : @link + * icp_qat_fw_point_multiplication_ed448_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_ed448_input_s::yp yp @endlink @link + * icp_qat_fw_point_multiplication_ed448_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_point_multiplication_ed448_output_s::xr xr @endlink @link + * icp_qat_fw_point_multiplication_ed448_output_s::yr yr @endlink + */ +#define GENERATOR_MULTIPLICATION_ED448 0x1a0a3536 +/**< Functionality ID for ECC edwards448 Generator Point Multiplication [k]P, as + * specified in RFC8032 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_ed448_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_generator_multiplication_ed448_output_s::xr xr @endlink @link + * icp_qat_fw_generator_multiplication_ed448_output_s::yr yr @endlink + */ +#define PKE_INIT 0x0806169f /**< Functionality ID for Initialisation sequence * @li 1 input parameters : @link icp_qat_fw_mmp_init_input_s::z z @endlink * @li 1 output parameters : @link icp_qat_fw_mmp_init_output_s::zz zz @endlink @@ -115,6 +271,22 @@ * icp_qat_fw_mmp_dh_4096_input_s::m m @endlink * @li 1 output parameters : @link icp_qat_fw_mmp_dh_4096_output_s::r r @endlink */ +#define PKE_DH_G2_8192 0x8d0b3626 +/**< Functionality ID for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers + * @li 2 input parameters : @link icp_qat_fw_mmp_dh_g2_8192_input_s::e e + * @endlink @link icp_qat_fw_mmp_dh_g2_8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_dh_g2_8192_output_s::r r + * @endlink + */ +#define PKE_DH_8192 0xcd0d3636 +/**< Functionality ID for Diffie-Hellman Modular exponentiation for 8192-bit + * numbers + * @li 3 input parameters : @link icp_qat_fw_mmp_dh_8192_input_s::g g @endlink + * @link icp_qat_fw_mmp_dh_8192_input_s::e e @endlink @link + * icp_qat_fw_mmp_dh_8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_dh_8192_output_s::r r @endlink + */ #define PKE_RSA_KP1_512 0x191d1a9a /**< Functionality ID for RSA 512 key generation first form * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_kp1_512_input_s::p p @@ -391,6 +563,33 @@ * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp2_4096_output_s::m m * @endlink */ +#define PKE_RSA_EP_8192 0xc31335c6 +/**< Functionality ID for RSA 8192 Encryption + * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_ep_8192_input_s::m m + * @endlink @link icp_qat_fw_mmp_rsa_ep_8192_input_s::e e @endlink @link + * icp_qat_fw_mmp_rsa_ep_8192_input_s::n n @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_ep_8192_output_s::c c + * @endlink + */ +#define PKE_RSA_DP1_8192 0xc31335e6 +/**< Functionality ID for RSA 8192 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_dp1_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_rsa_dp1_8192_input_s::d d @endlink @link + * icp_qat_fw_mmp_rsa_dp1_8192_input_s::n n @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp1_8192_output_s::m m + * @endlink + */ +#define PKE_RSA_DP2_8192 0xc9133606 +/**< Functionality ID for RSA 8192 Decryption with CRT + * @li 6 input parameters : @link icp_qat_fw_mmp_rsa_dp2_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_rsa_dp2_8192_input_s::p p @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::q q @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::dp dp @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::dq dq @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::qinv qinv @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp2_8192_output_s::m m + * @endlink + */ #define PKE_GCD_PT_192 0x19201fcd /**< Functionality ID for GCD primality test for 192-bit numbers * @li 1 input parameters : @link icp_qat_fw_mmp_gcd_pt_192_input_s::m m @@ -677,6 +876,14 @@ * @li 1 output parameters : @link icp_qat_fw_maths_modexp_l4096_output_s::r r * @endlink */ +#define MATHS_MODEXP_L8192 0xc50c3646 +/**< Functionality ID for Modular exponentiation for numbers up to 8192 bits + * @li 3 input parameters : @link icp_qat_fw_maths_modexp_l8192_input_s::g g + * @endlink @link icp_qat_fw_maths_modexp_l8192_input_s::e e @endlink @link + * icp_qat_fw_maths_modexp_l8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_maths_modexp_l8192_output_s::r r + * @endlink + */ #define MATHS_MODINV_ODD_L128 0x090623f8 /**< Functionality ID for Modular multiplicative inverse for numbers less than * 128 bits @@ -765,6 +972,14 @@ * @li 1 output parameters : @link icp_qat_fw_maths_modinv_odd_l4096_output_s::c * c @endlink */ +#define MATHS_MODINV_ODD_L8192 0x88073656 +/**< Functionality ID for Modular multiplicative inverse for numbers up to 8192 + * bits + * @li 2 input parameters : @link icp_qat_fw_maths_modinv_odd_l8192_input_s::a a + * @endlink @link icp_qat_fw_maths_modinv_odd_l8192_input_s::b b @endlink + * @li 1 output parameters : @link icp_qat_fw_maths_modinv_odd_l8192_output_s::c + * c @endlink + */ #define MATHS_MODINV_EVEN_L128 0x0906243a /**< Functionality ID for Modular multiplicative inverse for numbers less than * 128 bits @@ -853,6 +1068,14 @@ * @li 1 output parameters : @link * icp_qat_fw_maths_modinv_even_l4096_output_s::c c @endlink */ +#define MATHS_MODINV_EVEN_L8192 0xc80d3666 +/**< Functionality ID for Modular multiplicative inverse for numbers up to 8192 + * bits + * @li 2 input parameters : @link icp_qat_fw_maths_modinv_even_l8192_input_s::a + * a @endlink @link icp_qat_fw_maths_modinv_even_l8192_input_s::b b @endlink + * @li 1 output parameters : @link + * icp_qat_fw_maths_modinv_even_l8192_output_s::c c @endlink + */ #define PKE_DSA_GEN_P_1024_160 0x381824a4 /**< Functionality ID for DSA parameter generation P * @li 2 input parameters : @link icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s::x x @@ -1461,81 +1684,60 @@ * icp_qat_fw_maths_point_verify_gfp_521_input_s::b b @endlink * @li no output parameters */ -#define POINT_MULTIPLICATION_C25519 0x0a0634c6 -/**< Functionality ID for ECC curve25519 Variable Point Multiplication [k]P(x), - * as specified in RFC7748 - * @li 2 input parameters : @link - * icp_qat_fw_point_multiplication_c25519_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_c25519_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_point_multiplication_c25519_output_s::xr xr @endlink - */ -#define GENERATOR_MULTIPLICATION_C25519 0x0a0634d6 -/**< Functionality ID for ECC curve25519 Generator Point Multiplication [k]G(x), - * as specified in RFC7748 - * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_c25519_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_generator_multiplication_c25519_output_s::xr xr @endlink - */ -#define POINT_MULTIPLICATION_ED25519 0x100b34e6 -/**< Functionality ID for ECC edwards25519 Variable Point Multiplication [k]P, - * as specified in RFC8032 +#define PKE_EC_POINT_MULTIPLICATION_P256 0x0a083546 +/**< Functionality ID for ECC P256 Variable Point Multiplication [k]P(x) * @li 3 input parameters : @link - * icp_qat_fw_point_multiplication_ed25519_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_ed25519_input_s::yp yp @endlink @link - * icp_qat_fw_point_multiplication_ed25519_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::yp yp @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_point_multiplication_ed25519_output_s::xr xr @endlink @link - * icp_qat_fw_point_multiplication_ed25519_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p256_point_multiplication_output_s::xr xr @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_output_s::yr yr @endlink */ -#define GENERATOR_MULTIPLICATION_ED25519 0x100a34f6 -/**< Functionality ID for ECC edwards25519 Generator Point Multiplication [k]G, - * as specified in RFC8032 +#define PKE_EC_GENERATOR_MULTIPLICATION_P256 0x12073556 +/**< Functionality ID for ECC P256 Generator Point Multiplication [k]G(x) * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_ed25519_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p256_generator_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_generator_multiplication_ed25519_output_s::xr xr @endlink @link - * icp_qat_fw_generator_multiplication_ed25519_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p256_generator_multiplication_output_s::xr xr @endlink + * @link icp_qat_fw_mmp_ec_p256_generator_multiplication_output_s::yr yr + * @endlink */ -#define POINT_MULTIPLICATION_C448 0x0c063506 -/**< Functionality ID for ECC curve448 Variable Point Multiplication [k]P(x), as - * specified in RFC7748 - * @li 2 input parameters : @link - * icp_qat_fw_point_multiplication_c448_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_c448_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_point_multiplication_c448_output_s::xr xr @endlink +#define PKE_ECDSA_SIGN_RS_P256 0x18133566 +/**< Functionality ID for ECC P256 ECDSA Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s::r + * r @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s::s s @endlink */ -#define GENERATOR_MULTIPLICATION_C448 0x0c063516 -/**< Functionality ID for ECC curve448 Generator Point Multiplication [k]G(x), - * as specified in RFC7748 - * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_c448_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_generator_multiplication_c448_output_s::xr xr @endlink - */ -#define POINT_MULTIPLICATION_ED448 0x1a0b3526 -/**< Functionality ID for ECC edwards448 Variable Point Multiplication [k]P, as - * specified in RFC8032 +#define PKE_EC_POINT_MULTIPLICATION_P384 0x0b083586 +/**< Functionality ID for ECC P384 Variable Point Multiplication [k]P(x) * @li 3 input parameters : @link - * icp_qat_fw_point_multiplication_ed448_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_ed448_input_s::yp yp @endlink @link - * icp_qat_fw_point_multiplication_ed448_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::yp yp @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_point_multiplication_ed448_output_s::xr xr @endlink @link - * icp_qat_fw_point_multiplication_ed448_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p384_point_multiplication_output_s::xr xr @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_output_s::yr yr @endlink */ -#define GENERATOR_MULTIPLICATION_ED448 0x1a0a3536 -/**< Functionality ID for ECC edwards448 Generator Point Multiplication [k]P, as - * specified in RFC8032 +#define PKE_EC_GENERATOR_MULTIPLICATION_P384 0x0b073596 +/**< Functionality ID for ECC P384 Generator Point Multiplication [k]G(x) * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_ed448_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p384_generator_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_generator_multiplication_ed448_output_s::xr xr @endlink @link - * icp_qat_fw_generator_multiplication_ed448_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p384_generator_multiplication_output_s::xr xr @endlink + * @link icp_qat_fw_mmp_ec_p384_generator_multiplication_output_s::yr yr + * @endlink + */ +#define PKE_ECDSA_SIGN_RS_P384 0x1a1335a6 +/**< Functionality ID for ECC P384 ECDSA Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s::r + * r @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s::s s @endlink */ - #define PKE_LIVENESS 0x00000001 /**< Functionality ID for PKE_LIVENESS * @li 0 input parameter(s) @@ -1544,12 +1746,186 @@ #define PKE_INTERFACE_SIGNATURE 0x972ded54 /**< Encoded signature of the interface specifications */ - #define PKE_INVALID_FUNC_ID 0xffffffff +#define PKE_KPT_ECDSA_SIGN_RS_P521 0xb6563896 +/**< Functionality ID for ECC P521 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::kpt_wrapping_context + * kpt_wrapping_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s::s s @endlink + */ +#define PKE_KPT_ECDSA_SIGN_RS_P384 0x22143876 +/**< Functionality ID for ECC P384 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::kpt_wrapping_context + * kpt_wrapping_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s::s s @endlink + */ +#define PKE_KPT_ECDSA_SIGN_RS_P256 0x8d153856 +/**< Functionality ID for ECC KPT P256 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::key_unwrap_context + * key_unwrap_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s::s s @endlink + */ +#define PKE_KPT_RSA_DP1_512 0x1b1c3696 +/**< Functionality ID for KPT RSA 512 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::kpt_unwrap_context kpt_unwrap_context + * @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_512_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_1024 0x2d1d36b6 +/**< Functionality ID for KPT RSA 1024 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_1536 0x451d36d6 +/**< Functionality ID for KPT RSA 1536 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_2048 0x661936f6 +/**< Functionality ID for KPT RSA 2048 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_3072 0x751d3716 +/**< Functionality ID for KPT RSA 3072 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_4096 0x9d1d3736 +/**< Functionality ID for KPT RSA 4096 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_8192 0xbe203756 +/**< Functionality ID for KPT RSA 8192 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_512 0x241d3776 +/**< Functionality ID for RSA 512 decryption second form + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::kpt_unwrap_context kpt_unwrap_context + * @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_512_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_1024 0x4e1d3796 +/**< Functionality ID for RSA 1024 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_1536 0x762b37b6 +/**< Functionality ID for KPT RSA 1536 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_2048 0xa41a37d6 +/**< Functionality ID for RSA 2048 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_3072 0xd41a37f6 +/**< Functionality ID for + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_4096 0xd22a3816 +/**< Functionality ID for RSA 4096 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_8192 0xae383836 +/**< Functionality ID for RSA 8192 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_s::m m + * @endlink + */ #endif /* __ICP_QAT_FW_MMP_IDS__ */ -/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- - */ +/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- */ /* --- end of file --- */ diff --git a/sys/dev/qat/qat_api/include/cpa.h b/sys/dev/qat/qat_api/include/cpa.h index 359f50e3d896..f4baa90c45cf 100644 --- a/sys/dev/qat/qat_api/include/cpa.h +++ b/sys/dev/qat/qat_api/include/cpa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -418,8 +418,12 @@ typedef enum _CpaAccelerationServiceType /**< RAID */ CPA_ACC_SVC_TYPE_XML = CPA_INSTANCE_TYPE_XML, /**< XML */ - CPA_ACC_SVC_TYPE_VIDEO_ANALYTICS + CPA_ACC_SVC_TYPE_VIDEO_ANALYTICS, /**< Video Analytics */ + CPA_ACC_SVC_TYPE_CRYPTO_ASYM, + /**< Cryptography - Asymmetric service */ + CPA_ACC_SVC_TYPE_CRYPTO_SYM + /**< Cryptography - Symmetric service */ } CpaAccelerationServiceType; /** @@ -586,7 +590,7 @@ typedef struct _CpaInstanceInfo2 { CpaPhysicalInstanceId physInstId; /**< Identifies the "physical instance" of the accelerator. */ -#define CPA_MAX_CORES 256 +#define CPA_MAX_CORES 4096 /**< Maximum number of cores to support in the coreAffinity bitmap. */ CPA_BITMAP(coreAffinity, CPA_MAX_CORES); /**< A bitmap identifying the core or cores to which the instance @@ -670,6 +674,124 @@ typedef enum _CpaInstanceEvent */ } CpaInstanceEvent; +/*****************************************************************************/ +/* CPA Instance Management Functions */ +/*****************************************************************************/ +/** + ***************************************************************************** + * @file cpa.h + * @ingroup cpa + * Get the number of Acceleration Service instances that are supported by + * the API implementation. + * + * @description + * This function will get the number of instances that are supported + * for the required Acceleration Service by an implementation of the CPA + * API. This number is then used to determine the size of the array that + * must be passed to @ref cpaGetInstances(). + * + * @context + * This function MUST NOT be called from an interrupt context as it MAY + * sleep. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] accelerationServiceType Acceleration Service required + * @param[out] pNumInstances Pointer to where the number of + * instances will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * None + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated + * + * @see + * cpaGetInstances + * + *****************************************************************************/ +CpaStatus +cpaGetNumInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances); + +/** + ***************************************************************************** + * @file cpa.h + * @ingroup cpa + * Get the handles to the required Acceleration Service instances that are + * supported by the API implementation. + * + * @description + * This function will return handles to the required Acceleration Service + * instances that are supported by an implementation of the CPA API. These + * instance handles can then be used as input parameters with other + * API functions. + * + * This function will populate an array that has been allocated by the + * caller. The size of this array will have been determined by the + * cpaGetNumInstances() function. + * + * @context + * This function MUST NOT be called from an interrupt context as it MAY + * sleep. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] accelerationServiceType Acceleration Service requested + * @param[in] numInstances Size of the array. If the value is + * greater than the number of instances + * supported, then an error (@ref + * CPA_STATUS_INVALID_PARAM) is returned. + * @param[in,out] cpaInstances Pointer to where the instance + * handles will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * None + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated + * + * @see + * cpaGetNumInstances + * + *****************************************************************************/ +CpaStatus +cpaGetInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *cpaInstances); + #ifdef __cplusplus } /* close the extern "C" { */ #endif diff --git a/sys/dev/qat/qat_api/include/cpa_dev.h b/sys/dev/qat/qat_api/include/cpa_dev.h index 0beae449fccc..2d548e8a9541 100644 --- a/sys/dev/qat/qat_api/include/cpa_dev.h +++ b/sys/dev/qat/qat_api/include/cpa_dev.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/cpa_types.h b/sys/dev/qat/qat_api/include/cpa_types.h index 91781d390f62..00ed3c60fce6 100644 --- a/sys/dev/qat/qat_api/include/cpa_types.h +++ b/sys/dev/qat/qat_api/include/cpa_types.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,21 +132,6 @@ typedef int64_t Cpa64S; * NULL definition. */ #endif -#ifndef TRUE -#define TRUE (1==1) -/**< - * @file cpa_types.h - * @ingroup cpa_Types - * True value definition. */ -#endif -#ifndef FALSE -#define FALSE (0==1) -/**< - * @file cpa_types.h - * @ingroup cpa_Types - * False value definition. */ -#endif - /** ***************************************************************************** * @ingroup cpa_Types @@ -159,8 +144,8 @@ typedef int64_t Cpa64S; *****************************************************************************/ typedef enum _CpaBoolean { - CPA_FALSE = FALSE, /**< False value */ - CPA_TRUE = TRUE /**< True value */ + CPA_FALSE = (0==1), /**< False value */ + CPA_TRUE = (1==1) /**< True value */ } CpaBoolean; diff --git a/sys/dev/qat/qat_api/include/dc/cpa_dc.h b/sys/dev/qat/qat_api/include/dc/cpa_dc.h index 52d98a672646..f0ed869d1020 100644 --- a/sys/dev/qat/qat_api/include/dc/cpa_dc.h +++ b/sys/dev/qat/qat_api/include/dc/cpa_dc.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,16 @@ * @description * These functions specify the API for Data Compression operations. * + * The Data Compression API has the following: + * 1) Session based API functions + * These functions require a session to be created before performing any + * DC operations. Subsequent DC API functions make use of the returned + * Session Handle within their structures or function prototypes. + * 2) Session-less or No-Session (Ns) based API functions. + * These functions do not require a session to be initialized before + * performing DC operations. They are "one-shot" API function calls + * that submit DC requests directly using the supplied parameters. + * * @remarks * * @@ -78,7 +88,7 @@ extern"C" { * for this interface. * *****************************************************************************/ -#define CPA_DC_API_VERSION_NUM_MAJOR (2) +#define CPA_DC_API_VERSION_NUM_MAJOR (3) /** ***************************************************************************** @@ -93,6 +103,57 @@ extern"C" { *****************************************************************************/ #define CPA_DC_API_VERSION_NUM_MINOR (2) +/** + ***************************************************************************** + * @file cpa_dc.h + * @ingroup cpaDc + * CPA DC API version at least + * @description + * The minimal supported CPA_DC API version. Allow to check if the API + * version is equal or above some version to avoid compilation issues + * with an older API version. + * + *****************************************************************************/ +#define CPA_DC_API_VERSION_AT_LEAST(major, minor) \ + (CPA_DC_API_VERSION_NUM_MAJOR > major || \ + (CPA_DC_API_VERSION_NUM_MAJOR == major && \ + CPA_DC_API_VERSION_NUM_MINOR >= minor)) + +/** + ***************************************************************************** + * @file cpa_dc.h + * @ingroup cpaDc + * CPA DC API version less than + * @description + * The maximum supported CPA_DC API version. Allow to check if the API + * version is below some version to avoid compilation issues with a newer + * API version. + * + *****************************************************************************/ +#define CPA_DC_API_VERSION_LESS_THAN(major, minor) \ + (CPA_DC_API_VERSION_NUM_MAJOR < major || \ + (CPA_DC_API_VERSION_NUM_MAJOR == major && \ + CPA_DC_API_VERSION_NUM_MINOR < minor)) + +/** + ***************************************************************************** + * @ingroup cpaDc + * Size of bitmap needed for compression chaining capabilities. + * + * @description + * Defines the number of bits in the bitmap to represent supported + * chaining capabilities @ref dcChainCapInfo. Should be set to + * at least one greater than the largest value in the enumerated type + * @ref CpaDcChainOperations, so that the value of the enum constant + * can also be used as the bit position in the bitmap. + * + * A larger value was chosen to allow for extensibility without the need + * to change the size of the bitmap (to ease backwards compatibility in + * future versions of the API). + * + *****************************************************************************/ +#define CPA_DC_CHAIN_CAP_BITMAP_SIZE (32) + /** ***************************************************************************** * @ingroup cpaDc @@ -109,33 +170,6 @@ extern"C" { typedef void * CpaDcSessionHandle; -/** - ***************************************************************************** - * @ingroup cpaDc - * Supported file types - * - * @description - * This enumerated lists identified file types. Used to select Huffman - * trees. - * File types are associated with Precompiled Huffman Trees. - * - * @deprecated - * As of v1.6 of the Compression API, this enum has been deprecated. - * - *****************************************************************************/ -typedef enum _CpaDcFileType -{ - CPA_DC_FT_ASCII, - /**< ASCII File Type */ - CPA_DC_FT_CSS, - /**< Cascading Style Sheet File Type */ - CPA_DC_FT_HTML, - /**< HTML or XML (or similar) file type */ - CPA_DC_FT_JAVA, - /**< File Java code or similar */ - CPA_DC_FT_OTHER - /**< Other file types */ -} CpaDcFileType; /** ***************************************************************************** * @ingroup cpaDc @@ -185,7 +219,7 @@ typedef enum _CpaDcFlush *****************************************************************************/ typedef enum _CpaDcHuffType { - CPA_DC_HT_STATIC, + CPA_DC_HT_STATIC = 0, /**< Static Huffman Trees */ CPA_DC_HT_PRECOMP, /**< Precompiled Huffman Trees */ @@ -203,23 +237,73 @@ typedef enum _CpaDcHuffType * In combination with CpaDcChecksum it is used to decide on the file * header and footer format. * - * @deprecated - * As of v1.6 of the Compression API, CPA_DC_LZS, CPA_DC_ELZS and - * CPA_DC_LZSS have been deprecated and should not be used. - * *****************************************************************************/ typedef enum _CpaDcCompType { - CPA_DC_LZS, - /**< LZS Compression */ - CPA_DC_ELZS, - /**< Extended LZS Compression */ - CPA_DC_LZSS, - /**< LZSS Compression */ - CPA_DC_DEFLATE + CPA_DC_DEFLATE = 3, /**< Deflate Compression */ + CPA_DC_LZ4, + /**< LZ4 Compression */ + CPA_DC_LZ4S + /**< LZ4S Compression */ } CpaDcCompType; +/** + ***************************************************************************** + * @ingroup cpaDc + * Support for defined algorithm window sizes + * + * @description + * This enumerated list defines the valid window sizes that can be + * used with the supported algorithms + *****************************************************************************/ +typedef enum _CpaDcCompWindowSize +{ + CPA_DC_WINSIZE_4K = 0, + /**< Window size of 4KB */ + CPA_DC_WINSIZE_8K, + /**< Window size of 8KB */ + CPA_DC_WINSIZE_16K, + /**< Window size of 16KB */ + CPA_DC_WINSIZE_32K + /**< Window size of 32KB */ +} CpaDcCompWindowSize; + +/** + ***************************************************************************** + * @ingroup cpaDc + * Min match size in bytes + * @description + * This is the min match size that will be used for the search algorithm. + * It is only configurable for LZ4S. + *****************************************************************************/ +typedef enum _CpaDcCompMinMatch +{ + CPA_DC_MIN_3_BYTE_MATCH = 0, + /**< Min Match of 3 bytes */ + CPA_DC_MIN_4_BYTE_MATCH + /**< Min Match of 4 bytes */ +} CpaDcCompMinMatch; + +/** + ***************************************************************************** + * @ingroup cpaDc + * Maximum LZ4 output block size + * @description + * Maximum LZ4 output block size + *****************************************************************************/ +typedef enum _CpaDcCompLZ4BlockMaxSize +{ + CPA_DC_LZ4_MAX_BLOCK_SIZE_64K = 0, + /**< Maximum block size 64K */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_256K, + /**< Maximum block size 256K */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_1M, + /**< Maximum block size 1M */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_4M, + /**< Maximum block size 4M */ +} CpaDcCompLZ4BlockMaxSize; + /** ***************************************************************************** * @ingroup cpaDc @@ -232,12 +316,16 @@ typedef enum _CpaDcCompType *****************************************************************************/ typedef enum _CpaDcChecksum { - CPA_DC_NONE, - /**< No checksums required */ + CPA_DC_NONE = 0, + /**< No checksum required */ CPA_DC_CRC32, - /**< application requires a CRC32 checksum */ - CPA_DC_ADLER32 + /**< Application requires a CRC32 checksum */ + CPA_DC_ADLER32, /**< Application requires Adler-32 checksum */ + CPA_DC_CRC32_ADLER32, + /**< Application requires both CRC32 and Adler-32 checksums */ + CPA_DC_XXHASH32, + /**< Application requires xxHash-32 checksum */ } CpaDcChecksum; @@ -253,7 +341,7 @@ typedef enum _CpaDcChecksum *****************************************************************************/ typedef enum _CpaDcSessionDir { - CPA_DC_DIR_COMPRESS, + CPA_DC_DIR_COMPRESS = 0, /**< Session will be used for compression */ CPA_DC_DIR_DECOMPRESS, /**< Session will be used for decompression */ @@ -261,6 +349,8 @@ typedef enum _CpaDcSessionDir /**< Session will be used for both compression and decompression */ } CpaDcSessionDir; +typedef CpaDcSessionDir CpaDcDir; + /** ***************************************************************************** * @ingroup cpaDc @@ -280,13 +370,15 @@ typedef enum _CpaDcSessionDir *****************************************************************************/ typedef enum _CpaDcSessionState { - CPA_DC_STATEFUL, + CPA_DC_STATEFUL = 0, /**< Session will be stateful, implying that state may need to be saved in some situations */ CPA_DC_STATELESS /**< Session will be stateless, implying no state will be stored*/ } CpaDcSessionState; +typedef CpaDcSessionState CpaDcState; + /** ***************************************************************************** * @ingroup cpaDc @@ -316,8 +408,14 @@ typedef enum _CpaDcCompLvl /**< Compression level 7 */ CPA_DC_L8, /**< Compression level 8 */ - CPA_DC_L9 + CPA_DC_L9, /**< Compression level 9 */ + CPA_DC_L10, + /**< Compression level 10 */ + CPA_DC_L11, + /**< Compression level 11 */ + CPA_DC_L12 + /**< Compression level 12 */ } CpaDcCompLvl; /** @@ -384,6 +482,14 @@ typedef enum _CpaDcReqStatus * (not supported) */ CPA_DC_CRC_INTEG_ERR = -20, /**< A data integrity CRC error was detected */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_EXCEEDED = -93, + /**< LZ4 max block size exceeded */ + CPA_DC_LZ4_BLOCK_OVERFLOW_ERR = -95, + /**< LZ4 Block Overflow Error */ + CPA_DC_LZ4_TOKEN_IS_ZERO_ERR = -98, + /**< LZ4 Decoded token offset or token length is zero */ + CPA_DC_LZ4_DISTANCE_OUT_OF_RANGE_ERR = -100, + /**< LZ4 Distance out of range for len/distance pair */ } CpaDcReqStatus; /** @@ -393,11 +499,16 @@ typedef enum _CpaDcReqStatus * * @description * This enumeration lists the supported modes for automatically selecting - * the best Huffman encoding which would lead to the best compression - * results. + * the best encoding which would lead to the best compression results. * - * The CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS value is deprecated - * and should not be used. + * When CPA_DC_ASB_ENABLED is used the output will be a format compliant + * block, whether the data is compressed or not. + * + * The following values are deprecated and should not be used. They + * will be removed in a future version of this file. + * - CPA_DC_ASB_STATIC_DYNAMIC + * - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS + * - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS * *****************************************************************************/ typedef enum _CpaDcAutoSelectBest @@ -409,9 +520,11 @@ typedef enum _CpaDcAutoSelectBest CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS = 2, /**< Auto select between uncompressed, static and dynamic compression, * using stored block deflate headers if uncompressed is selected */ - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS = 3 + CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS = 3, /**< Auto select between uncompressed, static and dynamic compression, * using no deflate headers if uncompressed is selected */ + CPA_DC_ASB_ENABLED = 4, + /**< Auto select best mode is enabled */ } CpaDcAutoSelectBest; /** @@ -420,8 +533,8 @@ typedef enum _CpaDcAutoSelectBest * Supported modes for skipping regions of input or output buffers. * * @description - * This enumeration lists the supported modes for skipping regions of - * input or output buffers. + * This enumeration lists the supported modes for skipping regions of + * input or output buffers. * *****************************************************************************/ typedef enum _CpaDcSkipMode @@ -433,7 +546,7 @@ typedef enum _CpaDcSkipMode CPA_DC_SKIP_AT_END = 2, /**< Skip region is at the end of the buffer. */ CPA_DC_SKIP_STRIDE = 3 - /**< Skip region occurs at regular intervals within the buffer. + /**< Skip region occurs at regular intervals within the buffer. CpaDcSkipData.strideLength specifies the number of bytes between each skip region. */ } CpaDcSkipMode; @@ -547,21 +660,38 @@ typedef struct _CpaDcInstanceCapabilities { CpaBoolean statelessDeflateDecompression; /**sessType should be set to + * CPA_DC_CHAIN_COMPRESS_DECOMPRESS and pSessionData[]->pDcSetupData + * should point to a CpaDcSessionSetupData structure. + * + * -# For a symmetric crypto session, the corresponding + * pSessionData[]->sessType should be set to CPA_DC_CHAIN_SYMMETRIC_CRYPTO + * and pSessionData[]->pCySetupData should point to a + * CpaCySymSessionSetupData structure. + * + * -# Combined compression sessions are not supported for chaining. + * + * -# Stateful compression is not supported for chaining. + * + * -# Both CRC32 and Adler32 over the input data are supported for chaining. + * + * @see + * None + * + *****************************************************************************/ +CpaStatus +cpaDcChainInitSession(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + CpaDcCallbackFn callbackFn); + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Reset a compression chaining session. + * + * @description + * This function will reset a previously initialized session handle. + * Reset will fail if outstanding calls still exist for the initialized + * session handle. + * The client needs to retry the reset function at a later time. + * + * @context + * This is a synchronous function that cannot sleep. It can be + * executed in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * The session has been initialized via cpaDcChainInitSession function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcChainInitSession() + * + *****************************************************************************/ +CpaStatus +cpaDcChainResetSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle); + + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Remove a compression chaining session. + * + * @description + * This function will remove a previously initialized session handle + * and the installed callback handler function. Removal will fail if + * outstanding calls still exist for the initialized session handle. + * The client needs to retry the remove function at a later time. + * The memory for the session handle MUST not be freed until this call + * has completed successfully. + * + * @context + * This is a synchronous function that cannot sleep. It can be executed + * in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcChainInitSession() + * + *****************************************************************************/ +CpaStatus +cpaDcChainRemoveSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle); + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Submit a request to perform chaining operations. + * + * @description + * This function is used to perform chaining operations over data from + * the source buffer. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Target service instance. + * @param[in,out] pSessionHandle Session handle. + * @param[in] pSrcBuff Pointer to input data buffer. + * @param[out] pDestBuff Pointer to output data buffer. + * @param[in] operation Operation for the chaining request + * @param[in] numOpDatas The entries size CpaDcChainOpData array + * @param[in] pChainOpData Pointer to an array of CpaDcChainOpData + * structures. There should be numOpDatas + * entries in the array. + * @param[in,out] pResults Pointer to CpaDcChainRqResults structure. + * @param[in] callbackTag User supplied value to help correlate + * the callback with its associated request. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_DC_BAD_DATA The input data was not properly formed. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * pSessionHandle has been setup using cpaDcChainInitSession() + * @post + * pSessionHandle has session related state information + * @note + * This function passes control to the compression service for chaining + * processing, the supported chaining operations are described in + * CpaDcChainOperations. + * + * pChainOpData Setup Rules + * -# Each element in CpaDcChainOpData structure array holds either a + * (de)compression or a symmetric crypto operation data. + * + * -# The order of entries in pChainOpData[] must be consistent with the + * order of operations described for the chaining operation in + * CpaDcChainOperations. + * As an example, for CPA_DC_CHAIN_COMPRESS_THEN_ENCRYPT, pChainOpData[0] + * must contain the compression operation data and pChainOpData[1] must + * contain the encryption operation data. + * + * -# The numOpDatas for each chaining operation are specified in the + * comments for the operation in CpaDcChainOperations. + * + * -# For a (de)compression operation, the corresponding + * pChainOpData[]->opType should be set to + * CPA_DC_CHAIN_COMPRESS_DECOMPRESS and pChainOpData[]->pDcOp should + * point to a CpaDcOpData structure. + * + * -# For a symmetric crypto operation, the corresponding + * pChainOpData[]->opType should be set to + * CPA_DC_CHAIN_SYMMETRIC_CRYPTO and pChainOpData[]->pCySymOp should + * point to a CpaCySymOpData structure. + * + * -# Stateful compression is not supported for chaining. + * + * -# Partial packet processing is not supported. + * + * This function has identical buffer processing rules as + * cpaDcCompressData(). + * + * This function has identical checksum processing rules as + * cpaDcCompressData(), except: + * -# pResults->crc32 is available to application if + * CpaDcSessionSetupData->checksum is set to CPA_DC_CRC32 + * + * -# pResults->adler32 is available to application if + * CpaDcSessionSetupData->checksum is set to CPA_DC_ADLER32 + * + * -# Both pResults->crc32 and pResults->adler32 are available if + * CpaDcSessionSetupData->checksum is set to CPA_DC_CRC32_ADLER32 + * + * Synchronous or asynchronous operation of the API is determined by + * the value of the callbackFn parameter passed to cpaDcChainInitSession() + * when the sessionHandle was setup. If a non-NULL value was specified + * then the supplied callback function will be invoked asynchronously + * with the response of this request. + * + * This function has identical response ordering rules as + * cpaDcCompressData(). + * + * @see + * cpaDcCompressData + * + *****************************************************************************/ +CpaStatus +cpaDcChainPerformOp(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcChainOperations operation, + Cpa8U numOpDatas, + CpaDcChainOpData *pChainOpData, + CpaDcChainRqResults *pResults, + void *callbackTag ); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif + +#endif /* CPA_DC_CHAIN_H */ diff --git a/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h b/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h index 29511db2d102..1a08979bb941 100644 --- a/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h +++ b/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -143,7 +143,11 @@ typedef struct _CpaDcDpOpData /**< Instance to which the request is to be enqueued */ CpaDcSessionHandle pSessionHandle; - /**< DC Session associated with the stream of requests */ + /**< DC Session associated with the stream of requests. + * This field is only valid when using the session based API functions. + * This field must be set to NULL if the application wishes to use + * the No-Session (Ns) API. + */ CpaPhysicalAddr srcBuffer; /**< Physical address of the source buffer on which to operate. @@ -215,8 +219,18 @@ typedef struct _CpaDcDpOpData * It may be used to store information that might be useful when * processing the response later. */ -} CpaDcDpOpData; + CpaDcNsSetupData *pSetupData; + /**< Pointer to the No-session (Ns) Setup data for configuration of this + * request. + * + * This @ref CpaDcNsSetupData structure must be initialised when using the + * Data Plane No-Session (Ns) API. Otherwise it should be set to NULL. + * When initialized, the existing Data Plane API functions can be used + * as is. + */ + +} CpaDcDpOpData; /** ***************************************************************************** @@ -226,7 +240,7 @@ typedef struct _CpaDcDpOpData * @description * This is the callback function prototype. The callback function is * registered by the application using the @ref cpaDcDpRegCbFunc - * function call, and called back on completion of asycnhronous + * function call, and called back on completion of asynchronous * requests made via calls to @ref cpaDcDpEnqueueOp or @ref * cpaDcDpEnqueueOpBatch. * @@ -306,8 +320,8 @@ typedef void (*CpaDcDpCallbackFn)(CpaDcDpOpData *pOpData); * Only a synchronous version of this function is provided. * * Session data is expected to include interim checksum values, various - * counters and other other session related data that needs to persist - * between invocations. + * counters and other session related data that needs to persist between + * invocations. * For a given implementation of this API, it is safe to assume that * cpaDcDpGetSessionSize() will always return the same session size and * that the size will not be different for different setup data @@ -405,6 +419,65 @@ cpaDcDpInitSession( CpaInstanceHandle dcInstance, CpaDcSessionSetupData *pSessionData ); +/** + ***************************************************************************** + * @ingroup cpaDc + * Compression Session Update Function. + * + * @description + * This function is used to modify some select compression parameters + * of a previously initialized session handlei for a data plane session. + * Th update will fail if resources required for the new session settings + * are not available. Specifically, this function may fail if no + * intermediate buffers are associated with the instance, and the + * intended change would require these buffers. + * This function can be called at any time after a successful call of + * cpaDcDpInitSession(). + * This function does not change the parameters to compression request + * already in flight. + * + * @context + * This is a synchronous function that cannot sleep. It can be + * executed in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * No + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * @param[in] pSessionUpdateData Session Data. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * The session has been initialized via cpaDcDpInitSession function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcDpInitSession() + * + *****************************************************************************/ +CpaStatus cpaDcDpUpdateSession( const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pSessionUpdateData ); + /** ***************************************************************************** * @ingroup cpaDc @@ -468,7 +541,7 @@ cpaDcDpRemoveSession(const CpaInstanceHandle dcInstance, * @description * This function allows a completion callback function to be registered. * The registered callback function is invoked on completion of - * asycnhronous requests made via calls to @ref cpaDcDpEnqueueOp + * asynchronous requests made via calls to @ref cpaDcDpEnqueueOp * or @ref cpaDcDpEnqueueOpBatch. * @context * This is a synchronous function and it cannot sleep. It can be @@ -569,7 +642,8 @@ CpaStatus cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance, * * @pre * The session identified by pOpData->pSessionHandle was setup using - * @ref cpaDcDpInitSession. + * @ref cpaDcDpInitSession OR pOpData->pSetupData data structure was + * initialized for No-Session (Ns) usage. * The instance identified by pOpData->dcInstance has had a * callback function registered via @ref cpaDcDpRegCbFunc. * @@ -584,8 +658,6 @@ CpaStatus cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance, * @see * @ref cpaDcDpPerformOpNow *****************************************************************************/ - - CpaStatus cpaDcDpEnqueueOp(CpaDcDpOpData *pOpData, const CpaBoolean performOpNow); @@ -665,7 +737,8 @@ cpaDcDpEnqueueOp(CpaDcDpOpData *pOpData, * * @pre * The session identified by pOpData[i]->pSessionHandle was setup using - * @ref cpaDcDpInitSession. + * @ref cpaDcDpInitSession OR pOpData[i]->pSetupData data structure was + * initialized for No-Session (Ns) usage. * The instance identified by pOpData[i]->dcInstance has had a * callback function registered via @ref cpaDcDpRegCbFunc. * @@ -694,7 +767,7 @@ cpaDcDpEnqueueOpBatch(const Cpa32U numberRequests, * compression data plane API. * * @description - * This function triggers processing of previously enqueed requests on the + * This function triggers processing of previously enqueued requests on the * referenced instance. * * diff --git a/sys/dev/qat/qat_api/include/icp_sal_versions.h b/sys/dev/qat/qat_api/include/icp_sal_versions.h index 91719587445d..da44c030f4d4 100644 --- a/sys/dev/qat/qat_api/include/icp_sal_versions.h +++ b/sys/dev/qat/qat_api/include/icp_sal_versions.h @@ -27,7 +27,7 @@ /* Part name and number of the accelerator device */ #define SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER 3 -#define SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER 12 +#define SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER 13 #define SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER 0 /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h index aff4c717ac9f..92c262356e95 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ extern "C" { * for this interface. * *****************************************************************************/ -#define CPA_CY_API_VERSION_NUM_MAJOR (2) +#define CPA_CY_API_VERSION_NUM_MAJOR (3) /** ***************************************************************************** @@ -98,10 +98,43 @@ extern "C" { * this interface. * *****************************************************************************/ -#define CPA_CY_API_VERSION_NUM_MINOR (3) +#define CPA_CY_API_VERSION_NUM_MINOR (0) /** ***************************************************************************** + * @file cpa_cy_common.h + * @ingroup cpa_cyCommon + * CPA CY API version at least + * @description + * The minimal supported CPA_CY API version. Allow to check if the API + * version is equal or above some version to avoid compilation issues + * with an older API version. + * + *****************************************************************************/ +#define CPA_CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/** + ***************************************************************************** + * @file cpa_cy_common.h + * @ingroup cpa_cyCommon + * CPA CY API version less than + * @description + * The maximum supported CPA_CY API version. Allow to check if the API + * version is below some version to avoid compilation issues with a newer + * API version. + * + *****************************************************************************/ +#define CPA_CY_API_VERSION_LESS_THAN(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR < major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR < minor)) + +/** + ***************************************************************************** + * @file cpa_cy_common.h * @ingroup cpaCyCommon * Request priority * @description diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h index 0ee61e1f6c8d..57a77b8559f2 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,7 @@ typedef struct _CpaCyDhPhase1KeyGenOpData { CpaFlatBuffer primeP; /**< Flat buffer containing a pointer to the random odd prime number (p). * The bit-length of this number may be one of 768, 1024, 1536, 2048, - * 3072 or 4096. + * 3072, 4096 or 8192. */ CpaFlatBuffer baseG; /**< Flat buffer containing a pointer to base (g). This MUST comply with @@ -131,7 +131,7 @@ typedef struct _CpaCyDhPhase2SecretKeyGenOpData { CpaFlatBuffer primeP; /**< Flat buffer containing a pointer to the random odd prime number (p). * The bit-length of this number may be one of 768, 1024, 1536, 2048, - * 3072 or 4096. + * 3072, 4096 or 8192. * This SHOULD be same prime number as was used in the phase 1 key * generation operation. */ CpaFlatBuffer remoteOctetStringPV; @@ -230,7 +230,7 @@ typedef struct _CpaCyDhStats64 { * operations as defined in the PKCS #3 standard. It may be used to * generate the (local) octet string public value (PV) key. * The prime number sizes specified in RFC 2409, 4306, and part of - * RFC 3526 are supported (bit sizes 6144 and 8192 from RFC 3536 are not + * RFC 3526 are supported (bit size 6144 from RFC 3536 is not * supported). * * @context diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h index 01fc6f2f04b4..f7f51bf2aa7b 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h index f93a7ab10936..8f72bd669229 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ * 1. Montgomery 25519 Curve | scalar point Multiplication * Input: Montgomery affine coordinate X of point P * Scalar k - * Output: Montgomery affine coordinate X of point [k/P + * Output: Montgomery affine coordinate X of point [k]P * Decode: Scalar k always decoded by implementation * * 2. Montgomery 25519 Curve | generator point Multiplication @@ -80,13 +80,17 @@ * Scalar k * Output: Twisted Edwards affine coordinate X of point [k]P * Twisted Edwards affine coordinate Y of point [k]P - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 4. Twisted Edwards 25519 Curve | generator point Multiplication * Input: Scalar k * Output: Twisted Edwards affine coordinate X of point [k]G * Twisted Edwards affine coordinate Y of point [k]G - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 5. Montgomery 448 Curve | scalar point Multiplication * Input: Montgomery affine coordinate X of point P @@ -105,13 +109,17 @@ * Scalar k * Output: Edwards affine coordinate X of point [k]P * Edwards affine coordinate Y of point [k]P - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 8. Edwards 448 Curve | generator point Multiplication * Input: Scalar k * Output: Edwards affine coordinate X of point [k]G * Edwards affine coordinate Y of point [k]G - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * @note * Large numbers are represented on the QuickAssist API as described @@ -158,6 +166,35 @@ typedef enum _CpaCyEcFieldType /**< A binary field, GF(2^m) */ } CpaCyEcFieldType; +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Enumeration listing curve types to use with generic multiplication + * and verification routines. + * + * @description + * This structure contains a list of different elliptic curve types. + * EC Point multiplication and other operations depend on the type of + * the curve. + * + * @see + * cpaCyEcGenericPointMultiply() + * cpaCyEcGenericPointVerify() + * + *****************************************************************************/ +typedef enum _CpaCyEcCurveType +{ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_PRIME = 1, + /**< A Weierstrass curve with arithmetic in terms of the + * arithmetic of integers modulo p over a prime field. */ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_BINARY, + /**< A Weierstrass curve with arithmetic in terms of operations on bits + * over a binary field. */ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_KOBLITZ_BINARY, + /**< A Weierstrass-koblitz curve with arithmetic in terms of operations on + * the bits over a binary field. */ +} CpaCyEcCurveType; + /** ***************************************************************************** * @ingroup cpaCyEc @@ -175,16 +212,112 @@ typedef enum _CpaCyEcMontEdwdsCurveType CPA_CY_EC_MONTEDWDS_CURVE25519_TYPE = 1, /**< Montgomery 25519 curve */ CPA_CY_EC_MONTEDWDS_ED25519_TYPE, - /**< Twisted Edwards 25519 curve */ + /**< Edwards 25519 curve */ CPA_CY_EC_MONTEDWDS_CURVE448_TYPE, /**< Montgomery 448 curve */ CPA_CY_EC_MONTEDWDS_ED448_TYPE, - /**< Twisted Edwards 448 curve */ + /**< Edwards 448 curve */ } CpaCyEcMontEdwdsCurveType; /** ***************************************************************************** - * @file cpa_cy_ec.h + * @ingroup cpaCyEc + * Curve parameters for a Weierstrass type curve. + * + * @description + * This structure contains curve parameters for Weierstrass type + * curve: y^2 = x^3 + ax + b + * The client MUST allocate the memory for this structure + * When the structure is passed into the function, ownership of the memory + * passes to the function. Ownership of the memory returns to the client + * when this structure is returned in the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * The legend used in this structure is borrowed from RFC7748 + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the function, and before it + * has been returned in the callback, undefined behavior will result. + * + * @see + * CpaCyEcCurveParameters + * CpaCyEcFieldType + * + *****************************************************************************/ +typedef struct _CpaCyEcCurveParametersWeierstrass +{ + CpaCyEcFieldType fieldType; + /**< Prime or Binary */ + CpaFlatBuffer p; + /**< Prime modulus or irreducible polynomial over GF(2^m) */ + CpaFlatBuffer a; + /**< a coefficient */ + CpaFlatBuffer b; + /**< b coefficient */ + CpaFlatBuffer h; + /**< Cofactor */ +} CpaCyEcCurveParametersWeierstrass; + +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Union characterised by a specific curve. + * + * @description + * This union allows for the characterisation of different curve types + * encapsulted in one data type. The intention is that new curve types + * will be added in the future. + * + * @note + * + * @see + * CpaCyEcCurveParametersWeierstrass + * + *****************************************************************************/ +typedef union _CpaCyEcCurveParameters +{ + CpaCyEcCurveParametersWeierstrass weierstrassParameters; +} CpaCyEcCurveParameters; + +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Unified curve parameters. + * + * @description + * This structure provides a single data type that can describe a number + * of different curve types. The intention is to add further + * curve types in the future, thus the union field will allow for that + * expansion. + * + * The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the function, and before it + * has been returned in the callback, undefined behavior will result. + * + * @see + * CpaCyEcCurveParameters + * cpaCyEcGenericPointMultiply + * cpaCyEcGenericPointVerify + * + *****************************************************************************/ +typedef struct _CpaCyEcCurve +{ + CpaCyEcCurveType curveType; + CpaCyEcCurveParameters parameters; +} CpaCyEcCurve; + +/** + ***************************************************************************** * @ingroup cpaCyEc * EC Point Multiplication Operation Data. * @@ -230,8 +363,144 @@ typedef struct _CpaCyEcPointMultiplyOpData { * data pointer of the Flat Buffer to NULL. */ CpaCyEcFieldType fieldType; /**< field type for the operation */ -} CpaCyEcPointMultiplyOpData; +} CpaCyEcPointMultiplyOpData CPA_DEPRECATED; +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Generic EC Point Multiplication Operation Data. + * + * @description + * This structure contains a generic EC point and a multiplier for use with + * cpaCyEcGenericPointMultiply. This is common for representing all EC + * points, irrespective of curve type: Weierstrass, Montgomery and Twisted + * Edwards (at this time only Weierstrass are supported). The same + * point + multiplier format can be used when performing generator + * multiplication, in which case the xP, yP supplied in this structure will + * be ignored by QAT API library & a generator point will be inserted in + * their place. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcGenericPointMultiply + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcGenericPointMultiply() + * + *****************************************************************************/ +typedef struct _CpaCyEcGenericPointMultiplyOpData { + CpaFlatBuffer k; + /** 0 and k < n) */ + CpaFlatBuffer xP; + /** pair specified in the structure + * lies on the curve indicated in the cpaCyEcGenericPointVerify API. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcGenericPointVerify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcGenericPointVerify() + * + *****************************************************************************/ +typedef struct _CpaCyEcGenericPointVerifyOpData { + CpaFlatBuffer xP; + /** 0 and k < n) */ + CpaFlatBuffer xP; + /**< x coordinate of public key */ + CpaFlatBuffer yP; + /**< y coordinate of public key */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2EncryptOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Decryption Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Decrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Decrypt + * function, and before it has been returned in the callback, undefined + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Decrypt + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Decrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2DecryptOpData { + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaFlatBuffer x1; + /**< x coordinate of [k]G */ + CpaFlatBuffer y1; + /**< y coordinate of [k]G */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2DecryptOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Point Multiplication Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2PointMultiply + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2PointMultiply + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2PointMultiply() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2PointMultiplyOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2PointMultiplyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Generator Multiplication Operation Data. + * + * @description + * This structure contains the operation data for the + * cpaCyEcsm2GeneratorMultiply function. The client MUST allocate the + * memory for this structure and the items pointed to by this structure. + * When the structure is passed into the function, ownership of the + * memory passes to the function. Ownership of the memory returns to the + * client when this structure is returned in the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2GeneratorMultiply + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2GeneratorMultiply() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2GeneratorMultiplyOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2GeneratorMultiplyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Point Verify Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2PointVerify + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2PointVerify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2PointVerify() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2PointVerifyOpData { + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2PointVerifyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Signature Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Sign + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Sign + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Sign() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2SignOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaFlatBuffer e; + /**< digest of the message */ + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2SignOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Signature Verify Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Verify + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Verify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Verify() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2VerifyOpData { + CpaFlatBuffer e; + /**< digest of the message */ + CpaFlatBuffer r; + /**< signature r */ + CpaFlatBuffer s; + /**< signature s */ + CpaFlatBuffer xP; + /**< x coordinate of public key */ + CpaFlatBuffer yP; + /**< y coordinate of public key */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2VerifyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange Phase 1 Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2KeyExPhase1 + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2KeyExPhase1 + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2KeyExPhase1() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExPhase1OpData { + CpaFlatBuffer r; + /**< scalar multiplier (r > 0 and r < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2KeyExPhase1OpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange Phase 2 Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2KeyExPhase2 + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2KeyExPhase2 + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2KeyExPhase2() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExPhase2OpData { + CpaFlatBuffer r; + /**< scalar multiplier (r > 0 and r < n) */ + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaFlatBuffer x1; + /**< x coordinate of a point on the curve from other side */ + CpaFlatBuffer x2; + /**< x coordinate of a point on the curve from phase 1 */ + CpaFlatBuffer y2; + /**< y coordinate of a point on the curve from phase 1 */ + CpaFlatBuffer xP; + /**< x coordinate of public key from other side */ + CpaFlatBuffer yP; + /**< y coordinate of public key from other side */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2KeyExPhase2OpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Encryption Output Data. + * + * @description + * This structure contains the output data of the cpaCyEcsm2Encrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2Encrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2EncryptOutputData { + CpaFlatBuffer x1; + /**< x coordinate of [k]G */ + CpaFlatBuffer y1; + /**< y coordinate of [k]G */ + CpaFlatBuffer x2; + /**< x coordinate of [k]Pb */ + CpaFlatBuffer y2; + /**< y coordinate of [k]Pb */ +} CpaCyEcsm2EncryptOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Decryption Output Data. + * + * @description + * This structure contains the output data of the cpaCyEcsm2Decrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2Decrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2DecryptOutputData { + CpaFlatBuffer x2; + /**< x coordinate of [k]Pb */ + CpaFlatBuffer y2; + /**< y coordinate of [k]Pb */ +} CpaCyEcsm2DecryptOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange (Phase 1 & Phase 2) Output Data. + * + * @description + * This structure contains the output data of the key exchange(phase 1 & 2) + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2KeyExPhase1(),cpaCyEcsm2KeyExPhase2() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExOutputData { + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ +} CpaCyEcsm2KeyExOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Cryptographic ECSM2 Statistics. + * @description + * This structure contains statistics on the Cryptographic ECSM2 + * operations. Statistics are set to zero when the component is + * initialized, and are collected per instance. + * + ****************************************************************************/ +typedef struct _CpaCyEcsm2Stats64 { + Cpa64U numEcsm2PointMultiplyRequests; + /**< Total number of ECSM2 Point Multiplication operation requests. */ + Cpa64U numEcsm2PointMultiplyRequestErrors; + /**< Total number of ECSM2 Point Multiplication operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2PointMultiplyCompleted; + /**< Total number of ECSM2 Point Multiplication operation requests that + * completed successfully. */ + Cpa64U numEcsm2PointMultiplyCompletedError; + /**< Total number of ECSM2 Point Multiplication operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2PointMultiplyCompletedOutputInvalid; + /**< Total number of ECSM2 Point Multiplication or Point Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2GeneratorMultiplyRequests; + /**< Total number of ECSM2 Generator Multiplication operation requests. */ + Cpa64U numEcsm2GeneratorMultiplyRequestErrors; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2GeneratorMultiplyCompleted; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * completed successfully. */ + Cpa64U numEcsm2GeneratorMultiplyCompletedError; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2GeneratorMultiplyCompletedOutputInvalid; + /**< Total number of ECSM2 Generator Multiplication or Point Verify + * operation requests that could not be completed successfully due to an + * invalid output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2PointVerifyRequests; + /**< Total number of ECSM2 Point Verify operation requests. */ + Cpa64U numEcsm2PointVerifyRequestErrors; + /**< Total number of ECSM2 Point Verify operation requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2PointVerifyCompleted; + /**< Total number of ECSM2 Point Verify operation requests that + * completed successfully. */ + Cpa64U numEcsm2PointVerifyCompletedError; + /**< Total number of ECSM2 Point Verify operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2PointVerifyCompletedOutputInvalid; + /**< Total number of ECSM2 Point Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2SignRequests; + /**< Total number of ECSM2 Sign operation requests. */ + Cpa64U numEcsm2SignRequestErrors; + /**< Total number of ECSM2 Sign operation requests that had an error + * and could not be processed. */ + Cpa64U numEcsm2SignCompleted; + /**< Total number of ECSM2 Sign operation requests that completed + * successfully. */ + Cpa64U numEcsm2SignCompletedError; + /**< Total number of ECSM2 Sign operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2SignCompletedOutputInvalid; + /**< Total number of ECSM2 Sign operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2VerifyRequests; + /**< Total number of ECSM2 Verify operation requests. */ + Cpa64U numEcsm2VerifyRequestErrors; + /**< Total number of ECSM2 Verify operation requests that had an error + * and could not be processed. */ + Cpa64U numEcsm2VerifyCompleted; + /**< Total number of ECSM2 Verify operation requests that completed + * successfully. */ + Cpa64U numEcsm2VerifyCompletedError; + /**< Total number of ECSM2 Verify operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2VerifyCompletedOutputInvalid; + /**< Total number of ECSM2 Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2EncryptRequests; + /**< Total number of ECSM2 Encryption requests. */ + Cpa64U numEcsm2EncryptRequestErrors; + /**< Total number of ECSM2 Point Encryption requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2EncryptCompleted; + /**< Total number of ECSM2 Encryption operation requests that + * completed successfully. */ + Cpa64U numEcsm2EncryptCompletedError; + /**< Total number of ECSM2 Encryption operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2EncryptCompletedOutputInvalid; + /**< Total number of ECSM2 Encryption operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2DecryptRequests; + /**< Total number of ECSM2 Decryption operation requests. */ + Cpa64U numEcsm2DecryptRequestErrors; + /**< Total number of ECSM2 Point Decryption requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2DecryptCompleted; + /**< Total number of ECSM2 Decryption operation requests that + * completed successfully. */ + Cpa64U numEcsm2DecryptCompletedError; + /**< Total number of ECSM2 Decryption operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2DecryptCompletedOutputInvalid; + /**< Total number of ECSM2 Decryption operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2KeyExPhase1Requests; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests. */ + Cpa64U numEcsm2KeyExPhase1RequestErrors; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2KeyExPhase1Completed; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * completed successfully. */ + Cpa64U numEcsm2KeyExPhase1CompletedError; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2KeyExPhase1CompletedOutputInvalid; + /**< Total number of ECSM2 Key Exchange Phase1 operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2KeyExPhase2Requests; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests. */ + Cpa64U numEcsm2KeyExPhase2RequestErrors; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2KeyExPhase2Completed; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * completed successfully. */ + Cpa64U numEcsm2KeyExPhase2CompletedError; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2KeyExPhase2CompletedOutputInvalid; + /**< Total number of ECSM2 Key Exchange Phase2 operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ +} CpaCyEcsm2Stats64; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Definition of callback function invoked for cpaCyEcsm2Sign + * requests. + * + * @description + * This is the callback function for: + * cpaCyEcsm2Sign + * + * @context + * This callback function can be executed in a context that DOES NOT + * permit sleeping to occur. + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] status Status of the operation. Valid values are + * CPA_STATUS_SUCCESS and CPA_STATUS_FAIL. + * @param[in] pOpData A pointer to Operation data supplied in + * request. + * @param[in] pass Indicate whether pOut is valid or not. + * CPA_TRUE == pass, pOut is valid + * CPA_FALSE == pass, pOut is invalid + * @param[in] pR Ecsm2 message signature r. + * @param[in] pS Ecsm2 message signature s. + * + * @retval + * None + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * cpaCyEcsm2GeneratorMultiply() + * + *****************************************************************************/ +typedef void (*CpaCyEcsm2SignCbFunc)(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaBoolean pass, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Definition of callback function invoked for cpaCyEcsm2Verify requests. + * + * @description + * This is the prototype for the CpaCyEcsm2VerifyCbFunc callback function. + * + * @context + * This callback function can be executed in a context that DOES NOT + * permit sleeping to occur. + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] status Status of the operation. Valid values are + * CPA_STATUS_SUCCESS and CPA_STATUS_FAIL. + * @param[in] pOpData Operation data pointer supplied in request. + * @param[in] verifyStatus The verification status. + * + * @retval + * None + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * cpaCyEcsm2Verify() + * + *****************************************************************************/ +typedef void (*CpaCyEcsm2VerifyCbFunc)(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaBoolean verifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Point Multiplication. + * + * @description + * This function performs SM2 Point Multiplication, multiply + * a point (P) by k (scalar) ([k]P). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pMultiplyStatus Multiply status + * CPA_TRUE == pOutputData is valid + * CPA_FALSE == pOutputData is invalid + * @param[out] pXk x coordinate of the resulting point + * multiplication + * @param[out] pYk y coordinate of the resulting point + * multiplication + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2PointMultiplyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2PointMultiplyOpData, + * CpaCyEcPointMultiplyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2PointMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2PointMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Generator Multiplication. + * + * @description + * This function performs SM2 Generator Multiplication, multiply the + * generator point (G) by k (scalar) ([k]G). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pMultiplyStatus Multiply status + * CPA_TRUE == pOutputData is valid + * CPA_FALSE == pOutputData is invalid + * @param[out] pXk x coordinate of the resulting point + * multiplication + * @param[out] pYk y coordinate of the resulting point + * multiplication + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcPointMultiplyCbFunc is generated in response to this function + * call. For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2GeneratorMultiplyOpData, + * CpaCyEcPointMultiplyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2GeneratorMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2GeneratorMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Point Verify. + * + * @description + * This function performs SM2 Point Verify, to check if the input point + * on the curve or not. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pVerifyStatus Verification status + * CPA_TRUE == verify pass + * CPA_FALSE == verify fail + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2VerifyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2PointVerifyOpData, + * CpaCyEcPointVerifyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2PointVerify(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointVerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2PointVerifyOpData *pOpData, + CpaBoolean *pVerifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Signature (Step A4 to A7). + * + * @description + * This function implements step A4 to A7 (in Section 5.2 in "Generation + * of Signature" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pSignStatus Signature status + * CPA_TRUE = pOutputData is valid + * CPA_FALSE = pOutputData is invalid + * @param[out] pR R output of the resulting signature operation + * @param[out] pS S output of the resulting signature operation + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2SignCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2SignOpData, + * CpaCyEcsm2SignCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Sign(const CpaInstanceHandle instanceHandle, + const CpaCyEcsm2SignCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2SignOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Signature Verify (Step B5 to B7). + * + * @description + * This function implements step B5 to B7 (in Section 5.3 in "Verification + * of Signature" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pVerifyStatus Status of the signature verification + * CPA_TRUE == verify pass + * CPA_FALSE == verify fail + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2VerifyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2VerifyOpData, + * CpaCyEcsm2VerifyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Verify(const CpaInstanceHandle instanceHandle, + const CpaCyEcsm2VerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2VerifyOpData *pOpData, + CpaBoolean *pVerifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Encryption (Step A2 to A4). + * + * @description + * This function implements step A2 to A4 (in Section 7.2 in + * "Algorithm for Encryption and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Ecrypted message + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2EncryptOpData, + * CpaCyEcsm2EncryptOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Encrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2EncryptOpData *pOpData, + CpaCyEcsm2EncryptOutputData *pOutputData); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Decryption (Step B1 to B3). + * + * @description + * This function implements step B1 to B3 (in Section 7.3 in "Algorithm + * for Decryption and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Decrypted message + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2DecryptOpData, + * CpaCyEcsm2DecryptOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Decrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2DecryptOpData *pOpData, + CpaCyEcsm2DecryptOutputData *pOutputData); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Key Exchange Phase 1 (Step A2/B2). + * + * @description + * This function implements step A2 (User A) or B2 (User B) + * (in Section 6.2 in "Key Exchange Protocol and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Output of key exchange phase 1 ([r]G) + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2KeyExPhase1OpData, + * CpaCyEcsm2KeyExOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2KeyExPhase1(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase1OpData *pOpData, + CpaCyEcsm2KeyExOutputData *pOutputData); +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Key Exchange Phase 2 (Step A4 to A7, B3 to B6). + * + * @description + * This function implements steps A4 to A7(User A) or B3 to B6(User B) + * (in Section 6.2 in "Key Exchange Protocol and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Output of key exchange phase2. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2KeyExPhase2OpData, + * CpaCyEcsm2KeyExOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2KeyExPhase2(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase2OpData *pOpData, + CpaCyEcsm2KeyExOutputData *pOutputData); +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Query statistics for a specific ECSM2 instance. + * + * @description + * This function will query a specific instance of the ECSM2 implementation + * for statistics. The user MUST allocate the CpaCyEcsm2Stats64 structure + * and pass the reference to that structure into this function call. This + * function writes the statistic results into the passed in + * CpaCyEcsm2Stats64 structure. + * + * Note: statistics returned by this function do not interrupt current data + * processing and as such can be slightly out of sync with operations that + * are in progress during the statistics retrieval process. + * + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[out] pEcsm2Stats Pointer to memory into which the statistics + * will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * Component has been initialized. + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated. + * @see + * CpaCyEcsm2Stats64 + *****************************************************************************/ + +CpaStatus +cpaCyEcsm2QueryStats64(const CpaInstanceHandle instanceHandle_in, + CpaCyEcsm2Stats64 *pEcsm2Stats); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif + +#endif /*CPA_CY_ECSM2_H_*/ diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h index 25463a78cacc..2225e364f64a 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -242,6 +242,9 @@ typedef struct _CpaCyCapabilitiesInfo /**< CPA_TRUE if instance supports the Edwards and Montgomery elliptic * curves of the EC API. * See @ref cpaCyEc */ + CpaBoolean ecSm2Supported; + /**< CPA_TRUE if instance supports the EcSM2 API. + * See @ref cpaCyEcsm2. */ } CpaCyCapabilitiesInfo; /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h index 6162647b120b..3d013271e80b 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -151,8 +151,7 @@ typedef struct _CpaCyKeyGenSslOpData { * The length field indicates the length of the label in bytes. To use this * field, the sslOp must be CPA_CY_KEY_SSL_OP_USER_DEFINED, * or otherwise it is ignored and can be set to NULL. - * Implementation-specific limits - * may apply to this length. */ + * Implementation-specific limits may apply to this length. */ } CpaCyKeyGenSslOpData; /** @@ -298,7 +297,7 @@ typedef enum _CpaCyKeyHKDFCipherSuite #define CPA_CY_HKDF_SUBLABEL_FINISHED ((Cpa16U)0x0008) /**< Bit for creation of key material for 'finished' sublabel */ -#define CPA_CY_HKDF_KEY_MAX_SECRET_SZ ((Cpa8U)64) +#define CPA_CY_HKDF_KEY_MAX_SECRET_SZ ((Cpa8U)80) /** space in bytes PSK or (EC)DH */ #define CPA_CY_HKDF_KEY_MAX_HMAC_SZ ((Cpa8U)48) /** space in bytes of CPA_CY_SYM_HASH_SHA384 result */ @@ -346,7 +345,6 @@ typedef struct _CpaCyKeyGenHKDFExpandLabel /** ***************************************************************************** - * @file cpa_cy_key.h * @ingroup cpaCyKeyGen * TLS data for key generation functions * @description @@ -838,7 +836,6 @@ cpaCyKeyGenTls2(const CpaInstanceHandle instanceHandle, /** ***************************************************************************** - * @file cpa_cy_key.h * @ingroup cpaCyKeyGen * TLS Key Generation Function version 3. * @description diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h new file mode 100644 index 000000000000..612b86dbe488 --- /dev/null +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h @@ -0,0 +1,853 @@ +/*************************************************************************** + * + * BSD LICENSE + * + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/* + ***************************************************************************** + * Doxygen group definitions + ****************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * + * @defgroup cpaCyKpt Intel(R) Key Protection Technology (KPT) Cryptographic API + * + * @ingroup cpaCy + * + * @description + * These functions specify the APIs for Key Protection Technology (KPT) + * Cryptographic services. + * + * @note + * These functions implement the KPT Cryptographic API. + * This API is experimental and subject to change. + * + *****************************************************************************/ + +#ifndef __CPA_CY_KPT_H__ +#define __CPA_CY_KPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "cpa_cy_common.h" +#include "cpa_cy_rsa.h" +#include "cpa_cy_ecdsa.h" +#include "cpa_cy_ec.h" + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT wrapping key handle + * + * @description + * Handle to a unique wrapping key in wrapping key table. Application + * creates it in KPT key transfer phase and maintains it for KPT Crypto + * service. For each KPT Crypto service API invocation, this handle will + * be used to get a SWK(Symmetric Wrapping Key) to unwrap + * WPK(Wrapped Private Key) before performing the requested crypto + * service. + * + *****************************************************************************/ +typedef Cpa64U CpaCyKptHandle; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Return Status + * @description + * This enumeration lists all the possible return status after completing + * KPT APIs. + * + *****************************************************************************/ +typedef enum CpaCyKptKeyManagementStatus_t +{ + CPA_CY_KPT_SUCCESS = 0, + /**< Generic success status for all KPT wrapping key handling functions*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_VFID, + /**< SWK count exceeds the configured maxmium value per VFID*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_PASID, + /**< SWK count exceeds the configured maxmium value per PASID*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED, + /**< SWK count exceeds the configured maxmium value when not scoped to + * VFID or PASID*/ + CPA_CY_KPT_SWK_FAIL_NOT_FOUND, + /**< Unable to find SWK entry by handle */ + CPA_CY_KPT_FAILED, +} CpaCyKptKeyManagementStatus; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * PKCS#1 v2.2 RSA-3K signature output length in bytes. + * @see CpaCyKptValidationKey + * + *****************************************************************************/ +#define CPA_CY_RSA3K_SIG_SIZE_INBYTES 384 + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT device credentials key certificate + * @description + * This structure defines the key format for use with KPT. + * @see + * cpaCyKptQueryDeviceCredentials + * + *****************************************************************************/ +typedef struct CpaCyKptValidationKey_t +{ + CpaCyRsaPublicKey publicKey; + /**< Key */ + Cpa8U signature[CPA_CY_RSA3K_SIG_SIZE_INBYTES]; + /**< Signature of key */ +} CpaCyKptValidationKey; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Cipher algorithms used to generate a wrapped private key (WPK) from + * the clear private key. + * + * @description + * This enumeration lists supported cipher algorithms and modes. + * + *****************************************************************************/ +typedef enum CpaCyKptWrappingKeyType_t +{ + CPA_CY_KPT_WRAPPING_KEY_TYPE_AES256_GCM = 0 +} CpaCyKptWrappingKeyType; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT Loading key format specification. + * @description + * This structure defines the format of the symmetric wrapping key to be + * loaded into KPT. Application sets these parameters through the + * cpaCyKptLoadKey calls. + * + *****************************************************************************/ +typedef struct CpaCyKptLoadKey_t +{ + CpaFlatBuffer eSWK; + /**< Encrypted SWK */ + CpaCyKptWrappingKeyType wrappingAlgorithm; + /**< Symmetric wrapping algorithm */ +} CpaCyKptLoadKey; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Max length of initialization vector + * @description + * Defines the permitted max iv length in bytes that may be used in + * private key wrapping/unwrapping.For AEC-GCM, iv length is 12 bytes. + * + *@see cpaCyKptUnwrapContext + * + *****************************************************************************/ +#define CPA_CY_KPT_MAX_IV_LENGTH (12) + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Max length of Additional Authenticated Data + * @description + * Defines the permitted max aad length in bytes that may be used in + * private key wrapping/unwrapping. + * + *@see cpaCyKptUnwrapContext + * + *****************************************************************************/ +#define CPA_CY_KPT_MAX_AAD_LENGTH (16) + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Structure of KPT unwrapping context. + * @description + * This structure is a parameter of KPT crypto APIs, it contains data + * relating to KPT WPK unwrapping, the application needs to fill in this + * information. + * + *****************************************************************************/ +typedef struct CpaCyKptUnwrapContext_t +{ + CpaCyKptHandle kptHandle; + /**< This is application's unique handle that identifies its + * (symmetric) wrapping key*/ + Cpa8U iv[CPA_CY_KPT_MAX_IV_LENGTH]; + /**< Initialization Vector */ + Cpa8U additionalAuthData[CPA_CY_KPT_MAX_AAD_LENGTH]; + /**< A buffer holding the Additional Authenticated Data.*/ + Cpa32U aadLenInBytes; + /**< Number of bytes representing the size of AAD within additionalAuthData + * buffer. */ +} CpaCyKptUnwrapContext; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * RSA Private Key Structure For Representation 1. + * @description + * This structure contains the first representation that can be used for + * describing the RSA private key, represented by the tuple of the + * modulus (N) and the private exponent (D). + * The representation is encrypted as follows: + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * Key = SWK + * AAD = DER(OID) + * Input = (D || N) + * Encrypt (SWK, AAD, (D || N)) + * Output (AuthTag, (D || N)') + * EncryptedRSAKey = (D || N)' + * + * privateKey = (EncryptedRSAKey || AuthTag) + * + * OID's that shall be supported by KPT implementation: + * OID DER(OID) + * 1.2.840.113549.1.1 06 08 2A 86 48 86 F7 0D 01 01 + * + * Permitted lengths for N and D are: + * - 512 bits (64 bytes), + * - 1024 bits (128 bytes), + * - 1536 bits (192 bytes), + * - 2048 bits (256 bytes), + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). + * + * AuthTag is 128 bits (16 bytes) + * + * @note It is important that the value D is big enough. It is STRONGLY + * recommended that this value is at least half the length of the modulus + * N to protect against the Wiener attack. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKeyRep1_t +{ + CpaFlatBuffer privateKey; + /**< The EncryptedRSAKey concatenated with AuthTag */ +} CpaCyKptRsaPrivateKeyRep1; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT RSA Private Key Structure For Representation 2. + * @description + * This structure contains the second representation that can be used for + * describing the RSA private key. The quintuple of p, q, dP, dQ, and qInv + * (explained below and in the spec) are required for the second + * representation. For KPT the parameters are Encrypted + * with the assoicated SWK as follows: + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * Key = SWK + * AAD = DER(OID) + * Input = (P || Q || dP || dQ || Qinv || publicExponentE) + * Expanded Description: + * Encrypt (SWK, AAD, + * (P || Q || dP || dQ || Qinv || publicExponentE)) + * EncryptedRSAKey = (P || Q || dP || dQ || Qinv || publicExponentE)' + * Output (AuthTag, EncryptedRSAKey) + * + * privateKey = EncryptedRSAKey || AuthTag + * + * OID's that shall be supported by KPT implementation: + * OID DER(OID) + * 1.2.840.113549.1.1 06 08 2A 86 48 86 F7 0D 01 01 + * + * All of the encrypted parameters will be of equal size. The length of + * each will be equal to keySize in bytes/2. + * For example for a key size of 256 Bytes (2048 bits), the length of + * P, Q, dP, dQ, and Qinv are all 128 Bytes, plus the + * publicExponentE of 256 Bytes, giving a total size for + * EncryptedRSAKey of 896 Bytes. + * + * AuthTag is 128 bits (16 bytes) + * + * Permitted Key Sizes are: + * - 512 bits (64 bytes), + * - 1024 bits (128 bytes), + * - 1536 bits (192 bytes), + * - 2048 bits (256 bytes), + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKeyRep2_t +{ + CpaFlatBuffer privateKey; + /**< RSA private key representation 2 is built up from the + * tuple of p, q, dP, dQ, qInv, publicExponentE and AuthTag. + */ +} CpaCyKptRsaPrivateKeyRep2; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * RSA Private Key Structure. + * @description + * This structure contains the two representations that can be used for + * describing the RSA private key. The privateKeyRepType will be used to + * identify which representation is to be used. Typically, using the + * second representation results in faster decryption operations. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKey_t +{ + CpaCyRsaVersion version; + /**< Indicates the version of the PKCS #1 specification that is + * supported. + * Note that this applies to both representations. */ + CpaCyRsaPrivateKeyRepType privateKeyRepType; + /**< This value is used to identify which of the private key + * representation types in this structure is relevant. + * When performing key generation operations for Type 2 representations, + * memory must also be allocated for the type 1 representations, and values + * for both will be returned. */ + CpaCyKptRsaPrivateKeyRep1 privateKeyRep1; + /**< This is the first representation of the RSA private key as + * defined in the PKCS #1 V2.2 specification. */ + CpaCyKptRsaPrivateKeyRep2 privateKeyRep2; + /**< This is the second representation of the RSA private key as + * defined in the PKCS #1 V2.2 specification. */ +} CpaCyKptRsaPrivateKey; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT RSA Decryption Primitive Operation Data + * @description + * This structure lists the different items that are required in the + * cpaCyKptRsaDecrypt function. As the RSA decryption primitive and + * signature primitive operations are mathematically identical this + * structure may also be used to perform an RSA signature primitive + * operation. + * When performing an RSA decryption primitive operation, the input data + * is the cipher text and the output data is the message text. + * When performing an RSA signature primitive operation, the input data + * is the message and the output data is the signature. + * The client MUST allocate the memory for this structure. When the + * structure is passed into the function, ownership of the memory passes + * to he function. Ownership of the memory returns to the client when + * this structure is returned in the CpaCyGenFlatBufCbFunc + * callback function. + * + * @note + * If the client modifies or frees the memory referenced in this structure + * after it has been submitted to the cpaCyKptRsaDecrypt function, and + * before it has been returned in the callback, undefined behavior will + * result. + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. inputData.pData[0] = MSB. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaDecryptOpData_t +{ + CpaCyKptRsaPrivateKey *pRecipientPrivateKey; + /**< Pointer to the recipient's RSA private key. */ + CpaFlatBuffer inputData; + /**< The input data that the RSA decryption primitive operation is + * performed on. The data pointed to is an integer that MUST be in big- + * endian order. The value MUST be between 0 and the modulus n - 1. */ +} CpaCyKptRsaDecryptOpData; + + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT ECDSA Sign R & S Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyKptEcdsaSignRS + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * This key structure is encrypted when passed into cpaCyKptEcdsaSignRS + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * + * Key = SWK + * AAD = DER(OID) + * Input = (d) + * Encrypt (SWK, AAD, (d)) + * Output (AuthTag, EncryptedECKey) + * + * privatekey == EncryptedECKey || AuthTag + * + * OID's that shall be supported by KPT implementation: + * Curve OID DER(OID) + * secp256r1 1.2.840.10045.3.1.7 06 08 2A 86 48 CE 3D 03 01 07 + * secp384r1 1.3.132.0.34 06 05 2B 81 04 00 22 + * secp521r1 1.3.132.0.35 06 05 2B 81 04 00 23 + * + * Expected private key (d) sizes: + * secp256r1 256 bits + * secp384r1 384 bits + * secp521r1 576 bits (rounded up to a multiple of 64-bit quadword) + * + * AuthTag is 128 bits (16 bytes) + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyKptEcdsaSignRS + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcdsaSignRS() + * + *****************************************************************************/ +typedef struct CpaCyKptEcdsaSignRSOpData_t +{ + CpaFlatBuffer privateKey; + /**< Encrypted private key data of the form + * EncryptECKey || AuthTag */ + CpaFlatBuffer m; + /**< digest of the message to be signed */ +} CpaCyKptEcdsaSignRSOpData; + +/** + ***************************************************************************** + * Discovery and Provisioning APIs for KPT + * + *****************************************************************************/ + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Query KPT's issuing public key(R_Pu) and signature from QAT driver. + * @description + * This function is to query the RSA3K issuing key and its + * PKCS#1 v2.2 SHA-384 signature from the QAT driver. + * @context + * This function may sleep, and MUST NOT be called in interrupt context. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @param[in] instanceHandle Instance handle. + * @param[out] pIssueCert KPT-2.0 Issuing certificate in PEM format + as defined in RFC#7468 + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Issuing key retrieved successfully + * CPA_CY_KPT_FAILED Operation failed + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_FAIL Function failed. Suggested course of action + * is to shutdown and restart. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * Note that this is a synchronous function and has no completion callback + * associated with it. + * @see + * + *****************************************************************************/ + CpaStatus + cpaCyKptQueryIssuingKeys(const CpaInstanceHandle instanceHandle, + CpaFlatBuffer *pPublicX509IssueCert, + CpaCyKptKeyManagementStatus *pKptStatus); + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Query KPT's Per-Part public key(I_pu) and signature from QAT + * device + * @description + * This function is to query RSA3K Per-Part public key and its + * PKCS#1 v2.2 SHA-384 signature from the QAT device. + * @context + * This function may sleep, and MUST NOT be called in interrupt context. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @param[in] instanceHandle Instance handle. + * @param[out] pDevCredential Device Per-Part public key + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Device credentials retrieved successfully + * CPA_CY_KPT_FAILED Operation failed + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_FAIL Function failed. Suggested course of action + * is to shutdown and restart. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * Note that this is a synchronous function and has no completion callback + * associated with it. + * @see + * + *****************************************************************************/ + CpaStatus + cpaCyKptQueryDeviceCredentials(const CpaInstanceHandle instanceHandle, + CpaCyKptValidationKey *pDevCredential, + CpaCyKptKeyManagementStatus *pKptStatus); + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT key loading function. + * + * @description + * This function is invoked by a QAT application to load an encrypted + * symmetric wrapping key. + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle QAT service instance handle. + * @param[in] pSWK Encrypted SWK + * @param[out] keyHandle A 64-bit handle value created by KPT + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Key Loaded successfully + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_VFID + * SWK count exceeds the configured maxmium value per VFID + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_PASID + * SWK count exceeds the configured maxmium value per PASID + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED + * SWK count exceeds the configured maxmium value when not scoped to + * VFID or PASID + * CPA_CY_KPT_FAILED Operation failed due to unspecified reason + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * @retval CPA_STATUS_UNSUPPORTED KPT-2.0 is not supported. + * + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * None + *****************************************************************************/ + CpaStatus + cpaCyKptLoadKey(CpaInstanceHandle instanceHandle, + CpaCyKptLoadKey *pSWK, + CpaCyKptHandle *keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus); + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT delete keys function according to key handle + * + * @description + * Before closing a QAT session(instance), an application that has + * previously stored its wrapping key in a QAT device using the KPT + * framework executes this call to delete its wrapping key in the QAT + * device. + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle QAT service instance handle. + * @param[in] keyHandle A 64-bit handle value + * @param[out] pkptstatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Key Deleted successfully + * CPA_CY_KPT_SWK_FAIL_NOT_FOUND For any reason the input handle cannot be + * found. + * CPA_CY_KPT_FAILED Operation failed due to unspecified reason + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * None + *****************************************************************************/ +CpaStatus +cpaCyKptDeleteKey(CpaInstanceHandle instanceHandle, + CpaCyKptHandle keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus); + +/** +***************************************************************************** +* Usage APIs for KPT +* +*****************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT-2.0 mode RSA decrypt primitive operation on the input data. + * + * @description + * This function is a variant of cpaCyRsaDecrypt, which will perform + * an RSA decryption primitive operation on the input data using the + * specified RSA private key which are encrypted. As the RSA decryption + * primitive and signing primitive operations are mathematically + * identical this function may also be used to perform an RSA signing + * primitive operation. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pRsaDecryptCb Pointer to callback function to be invoked + * when the operation is complete. If this is + * set to a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag Opaque User Data for this specific call. + * Will be returned unchanged in the callback. + * @param[in] pDecryptOpData Structure containing all the data needed to + * perform the RSA decrypt operation. The + * client code allocates the memory for this + * structure. This component takes ownership + * of the memory until it is returned in the + * callback. + * @param[out] pOutputData Pointer to structure into which the result of + * the RSA decryption primitive is written. The + * client MUST allocate this memory. The data + * pointed to is an integer in big-endian order. + * The value will be between 0 and the modulus + * n - 1. + * On invocation the callback function will + * contain this parameter in the pOut parameter. + * @param[in] pKptUnwrapContext Pointer of structure into which the content + * of KptUnwrapContext is kept. The client MUST + * allocate this memory and copy structure + * KptUnwrapContext into this flat buffer. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting.Resubmit + * the request. + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * By virtue of invoking cpaSyKptRsaDecrypt, the implementation understands + * that pDecryptOpData contains an encrypted private key that requires + * unwrapping. KptUnwrapContext contains a 'KptHandle' field that points + * to the unwrapping key in the WKT. + * When pRsaDecryptCb is non-NULL an asynchronous callback is generated in + * response to this function call. + * Any errors generated during processing are reported as part of the + * callback status code. For optimal performance, data pointers SHOULD be + * 8-byte aligned. + * In KPT release, private key field in CpaCyKptRsaDecryptOpData is a + * concatenation of cipher text and hash tag. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * @see + * CpaCyKptRsaDecryptOpData, + * CpaCyGenFlatBufCbFunc, + * + *****************************************************************************/ +CpaStatus +cpaCyKptRsaDecrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pRsaDecryptCb, + void *pCallbackTag, + const CpaCyKptRsaDecryptOpData *pDecryptOpData, + CpaFlatBuffer *pOutputData, + CpaCyKptUnwrapContext *pKptUnwrapContext); + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Generate ECDSA Signature R & S. + * @description + * This function is a variant of cpaCyEcdsaSignRS, it generates ECDSA + * signature R & S as per ANSI X9.62 2005 section 7.3. + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pSignStatus In synchronous mode, the multiply output is + * valid (CPA_TRUE) or the output is invalid + * (CPA_FALSE). + * @param[out] pR ECDSA message signature r. + * @param[out] pS ECDSA message signature s. + * @param[in] pKptUnwrapContext Pointer of structure into which the content + * of KptUnwrapContext is kept,The client MUST + * allocate this memory and copy structure + * KptUnwrapContext into this flat buffer. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * By virtue of invoking the cpaCyKptEcdsaSignRS, the implementation + * understands CpaCyEcdsaSignRSOpData contains an encrypted private key that + * requires unwrapping. KptUnwrapContext contains a 'KptHandle' field + * that points to the unwrapping key in the WKT. + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcdsaSignRSCbFunc generated in response to this function + * call. + * In KPT release, private key field in CpaCyEcdsaSignRSOpData is a + * concatenation of cipher text and hash tag. + * @see + * None + *****************************************************************************/ +CpaStatus +cpaCyKptEcdsaSignRS(const CpaInstanceHandle instanceHandle, + const CpaCyEcdsaSignRSCbFunc pCb, + void *pCallbackTag, + const CpaCyKptEcdsaSignRSOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS, + CpaCyKptUnwrapContext *pKptUnwrapContext); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif +#endif diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h index d5790bff6c66..43550cdb0fed 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,8 +76,8 @@ * MSB is b[0]. Otherwise, all bytes from b[0] up to the MSB MUST be * set to 0x00. * - * The largest bit-length we support today is 4096 bits. In other - * words, we can deal with numbers up to a value of (2^4096)-1. + * The largest bit-length we support today is 8192 bits. In other + * words, we can deal with numbers up to a value of (2^8192)-1. * *****************************************************************************/ @@ -110,21 +110,21 @@ extern "C" { * result. * The values of the base, the exponent and the modulus MUST all be less - * than 2^4096, and the modulus must not be equal to zero. + * than 2^8192, and the modulus must not be equal to zero. *****************************************************************************/ typedef struct _CpaCyLnModExpOpData { CpaFlatBuffer modulus; /**< Flat buffer containing a pointer to the modulus. - * This number may be up to 4096 bits in length, and MUST be greater + * This number may be up to 8192 bits in length, and MUST be greater * than zero. */ CpaFlatBuffer base; /**< Flat buffer containing a pointer to the base. - * This number may be up to 4096 bits in length. + * This number may be up to 8192 bits in length. */ CpaFlatBuffer exponent; /**< Flat buffer containing a pointer to the exponent. - * This number may be up to 4096 bits in length. + * This number may be up to 8192 bits in length. */ } CpaCyLnModExpOpData; @@ -146,19 +146,19 @@ typedef struct _CpaCyLnModExpOpData { * result. * * Note that the values of A and B MUST NOT both be even numbers, and - * both MUST be less than 2^4096. + * both MUST be less than 2^8192. *****************************************************************************/ typedef struct _CpaCyLnModInvOpData { CpaFlatBuffer A; /**< Flat buffer containing a pointer to the value that will be * inverted. - * This number may be up to 4096 bits in length, it MUST NOT be zero, + * This number may be up to 8192 bits in length, it MUST NOT be zero, * and it MUST be co-prime with B. */ CpaFlatBuffer B; /**< Flat buffer containing a pointer to the value that will be used as * the modulus. - * This number may be up to 4096 bits in length, it MUST NOT be zero, + * This number may be up to 8192 bits in length, it MUST NOT be zero, * and it MUST be co-prime with A. */ } CpaCyLnModInvOpData; diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h index 21e2b1e9081f..7065304f69e8 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h index a9ca9595bad8..a72950ecd970 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -138,8 +138,9 @@ typedef struct _CpaCyRsaPrivateKeyRep1 { * - 1024 bits (128 bytes), * - 1536 bits (192 bytes), * - 2048 bits (256 bytes), - * - 3072 bits (384 bytes), or - * - 4096 bits (512 bytes). + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). */ CpaFlatBuffer privateExponentD; /**< The private exponent (d). For key generation operations the @@ -467,6 +468,17 @@ typedef struct _CpaCyRsaStats64 { Cpa64U numRsaDecryptCompletedErrors; /**< Total number of RSA decrypt operations that could not be * completed successfully due to errors. */ + Cpa64U numKptRsaDecryptRequests; + /**< Total number of successful KPT RSA decrypt operation requests. */ + Cpa64U numKptRsaDecryptRequestErrors; + /**< Total number of KPT RSA decrypt requests that had an error and could + * not be processed. */ + Cpa64U numKptRsaDecryptCompleted; + /**< Total number of KPT RSA decrypt operations that completed + * successfully. */ + Cpa64U numKptRsaDecryptCompletedErrors; + /**< Total number of KPT RSA decrypt operations that could not be + * completed successfully due to errors. */ } CpaCyRsaStats64; /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h index 416f4aa4bea8..934ad2520774 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -372,17 +372,17 @@ typedef enum _CpaCySymHashAlgorithm * CPA_CY_SYM_HASH_MODE_AUTH. Only 128-bit keys are supported. */ CPA_CY_SYM_HASH_ZUC_EIA3, /**< ZUC algorithm in EIA3 mode */ - CPA_CY_SYM_HASH_SHA3_224, - /**< 224 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and - * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash - * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. - */ CPA_CY_SYM_HASH_SHA3_256, /**< 256 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. * Partial requests are not supported, that is, only requests * of CPA_CY_SYM_PACKET_TYPE_FULL are supported. */ + CPA_CY_SYM_HASH_SHA3_224, + /**< 224 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and + * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash + * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. + */ CPA_CY_SYM_HASH_SHA3_384, /**< 384 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash @@ -1453,7 +1453,7 @@ cpaCySymUpdateSession(CpaCySymSessionCtx sessionCtx, *****************************************************************************/ CpaStatus cpaCySymSessionInUse(CpaCySymSessionCtx sessionCtx, - CpaBoolean* pSessionInUse); + CpaBoolean* pSessionInUse); /** ***************************************************************************** @@ -1519,6 +1519,9 @@ cpaCySymSessionInUse(CpaCySymSessionCtx sessionCtx, * - The cipher algorithm is not CPA_CY_SYM_CIPHER_CHACHA and the hash * algorithm is not CPA_CY_SYM_HASH_POLY. * + * - The cipher algorithm is not CPA_CY_SYM_CIPHER_AES_GCM and the hash + * algorithm is not CPA_CY_SYM_HASH_AES_GCM. + * * - The instance/implementation supports partial packets as one of * its capabilities (see @ref CpaCySymCapabilitiesInfo). * diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h index df6cc922b45d..479cb72c2cf2 100644 --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h b/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h index 82df3bb00d19..bfc273c7328f 100644 --- a/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h +++ b/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h @@ -98,7 +98,10 @@ typedef enum device_type_e { DEVICE_200XXVF, DEVICE_C4XXX, DEVICE_C4XXXVF, - DEVICE_GEN4 + DEVICE_D15XX, + DEVICE_D15XXVF, + DEVICE_4XXX, + DEVICE_4XXXVF } device_type_t; /* diff --git a/sys/dev/qat/qat_common/adf_aer.c b/sys/dev/qat/qat_common/adf_aer.c index 9ac7c8edd72b..a2307e690790 100644 --- a/sys/dev/qat/qat_common/adf_aer.c +++ b/sys/dev/qat/qat_common/adf_aer.c @@ -284,8 +284,6 @@ adf_notify_fatal_error_work(struct work_struct *work) adf_error_notifier((uintptr_t)accel_dev); if (!accel_dev->is_vf) { - if (accel_dev->u1.pf.vf_info) - adf_pf2vf_notify_fatal_error(accel_dev); adf_dev_autoreset(accel_dev); } diff --git a/sys/dev/qat/qat_common/adf_cfg.c b/sys/dev/qat/qat_common/adf_cfg.c index 1f6cf6c1732d..397414a02ddd 100644 --- a/sys/dev/qat/qat_common/adf_cfg.c +++ b/sys/dev/qat/qat_common/adf_cfg.c @@ -5,6 +5,8 @@ #include "adf_cfg.h" #include "adf_common_drv.h" #include "adf_cfg_dev_dbg.h" +#include "adf_cfg_device.h" +#include "adf_cfg_sysctl.h" #include "adf_heartbeat_dbg.h" #include "adf_ver_dbg.h" #include "adf_fw_counters.h" @@ -30,8 +32,54 @@ adf_cfg_dev_add(struct adf_accel_dev *accel_dev) sx_init(&dev_cfg_data->lock, "qat cfg data"); accel_dev->cfg = dev_cfg_data; + /* Default device configuration initialization */ + if (!accel_dev->is_vf) { + + if (IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev)))) { + dev_cfg_data->num_user_processes = + ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM; + + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL_USER, + ADF_CFG_MAX_VAL); + + if (accel_dev->accel_id % 2 == 0) { + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_SYM_ASYM, + ADF_CFG_MAX_VAL); + } else { + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_DC, + ADF_CFG_MAX_VAL); + } + } else { + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL, + ADF_CFG_MAX_VAL); + dev_cfg_data->num_user_processes = 0; + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_SYM_DC, + ADF_CFG_MAX_VAL); + } + } else { + dev_cfg_data->num_user_processes = + ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM; + + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL, + ADF_CFG_MAX_VAL); + + strncpy(dev_cfg_data->cfg_services, + "sym;asym", + ADF_CFG_MAX_VAL); + } + + if (adf_cfg_sysctl_add(accel_dev)) + goto err; + if (adf_cfg_dev_dbg_add(accel_dev)) goto err; + if (!accel_dev->is_vf) { if (adf_heartbeat_dbg_add(accel_dev)) goto err; @@ -94,6 +142,7 @@ adf_cfg_dev_remove(struct adf_accel_dev *accel_dev) adf_cfg_section_del_all(&dev_cfg_data->sec_list); sx_xunlock(&dev_cfg_data->lock); + adf_cfg_sysctl_remove(accel_dev); adf_cfg_dev_dbg_remove(accel_dev); if (!accel_dev->is_vf) { adf_ver_dbg_del(accel_dev); diff --git a/sys/dev/qat/qat_common/adf_cfg_device.c b/sys/dev/qat/qat_common/adf_cfg_device.c index 9e59c038f2f3..a5fce6905473 100644 --- a/sys/dev/qat/qat_common/adf_cfg_device.c +++ b/sys/dev/qat/qat_common/adf_cfg_device.c @@ -7,7 +7,7 @@ #include "icp_qat_hw.h" #include "adf_common_drv.h" -#define ADF_CFG_SVCS_MAX (25) +#define ADF_CFG_SVCS_MAX (12) #define ADF_CFG_DEPRE_PARAMS_NUM (4) #define ADF_CFG_CAP_DC ADF_ACCEL_CAPABILITIES_COMPRESSION @@ -83,6 +83,14 @@ static struct adf_cfg_profile adf_profiles[] = ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + { "asym;sym", + ADF_CFG_CY_RINGS, + ADF_CFG_CAP_CY, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + { "sym;asym", + ADF_CFG_CY_RINGS, + ADF_CFG_CAP_CY, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, { "sym", ADF_CFG_SYM_RINGS, @@ -116,57 +124,6 @@ static struct adf_cfg_profile adf_profiles[] = ADF_CFG_SYM_DC_RINGS, ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;sym", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "sym;inline", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;asym", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "asym;inline", - ADF_CFG_ASYM_RINGS, - ADF_CFG_CAP_ASYM, - ADF_CFG_FW_CAP_ECEDMONT }, - { "inline", 0, 0, 0 }, - { "inline;cy", - ADF_CFG_CY_RINGS, - ADF_CFG_CAP_CY, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "cy;inline", - ADF_CFG_CY_RINGS, - ADF_CFG_CAP_CY, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;inline", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, - { "inline;dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, - { "cy;dc;inline", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "cy;inline;dc", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;inline;cy", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;cy;inline", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;cy;dc", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;dc;cy", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, } }, { ADF_FW_IMAGE_CRYPTO, { @@ -174,8 +131,7 @@ static struct adf_cfg_profile adf_profiles[] = ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "sym", ADF_CFG_SYM_RINGS, ADF_CFG_CAP_SYM, @@ -196,8 +152,7 @@ static struct adf_cfg_profile adf_profiles[] = ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, { "sym", ADF_CFG_SYM_RINGS, @@ -212,14 +167,12 @@ static struct adf_cfg_profile adf_profiles[] = ADF_CFG_CY_DC_RINGS, ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc;cy", ADF_CFG_CY_DC_RINGS, ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "asym;dc", ADF_CFG_ASYM_DC_RINGS, ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC, @@ -380,9 +333,34 @@ adf_cfg_get_services_enabled(struct adf_accel_dev *accel_dev, void adf_cfg_set_asym_rings_mask(struct adf_accel_dev *accel_dev) { + int service; + u16 ena_srv_mask; + u16 service_type; + u16 asym_mask = 0; + struct adf_cfg_device *cfg_dev = accel_dev->cfg->dev; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - hw_data->asym_rings_mask = 0; + if (!cfg_dev) { + hw_data->asym_rings_mask = ADF_CFG_DEF_ASYM_MASK; + return; + } + + ena_srv_mask = accel_dev->hw_device->ring_to_svc_map; + + /* parse each service */ + for (service = 0; service < ADF_CFG_MAX_SERVICES; service++) { + service_type = GET_SRV_TYPE(ena_srv_mask, service); + switch (service_type) { + case CRYPTO: + case ASYM: + SET_ASYM_MASK(asym_mask, service); + if (service_type == CRYPTO) + service++; + break; + } + } + + hw_data->asym_rings_mask = asym_mask; } void @@ -579,7 +557,6 @@ adf_cfg_update_vf_accel_cap_mask(struct adf_accel_dev *accel_dev) { u32 enabled_svc_caps = 0; u32 enabled_fw_caps = 0; - if (adf_cfg_get_caps_enabled(accel_dev, &enabled_svc_caps, &enabled_fw_caps)) @@ -701,6 +678,272 @@ adf_cfg_device_clear(struct adf_cfg_device *device, device->instances = NULL; } +/* + * Static configuration for userspace + */ +static int +adf_cfg_static_conf_user(struct adf_accel_dev *accel_dev, + int cy_enabled, + int dc_enabled) +{ + int ret = 0; + unsigned long val = 0; + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + int cy_user_instances = 0; + int dc_user_instances = 0; + int i = 0; + int cpus = num_online_cpus(); + + if (!(IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev))))) { + device_printf( + GET_DEV(accel_dev), + "User space configuration supported only on QAT 4xxx devices\n"); + return ENXIO; + } + + ret |= adf_cfg_section_add(accel_dev, ADF_SAL_SEC); + + if (accel_dev->is_vf) { + if (cy_enabled) + cy_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_CY_VF; + + if (dc_enabled) + dc_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_DC_VF; + } else { + if (cy_enabled) + cy_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_CY; + + if (dc_enabled) + dc_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_DC; + } + + val = cy_user_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = dc_user_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = accel_dev->cfg->num_user_processes; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_PROCESSES); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + for (i = 0; i < cy_user_instances; i++) { + val = (accel_dev->accel_id * cy_user_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = 0; i < dc_user_instances; i++) { + val = (accel_dev->accel_id * dc_user_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR); + } + + return ret; +} + +static int +adf_cfg_static_conf_kernel(struct adf_accel_dev *accel_dev, + int asym_enabled, + int sym_enabled, + int dc_enabled) +{ + int ret = 0; + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + unsigned long val = 0; + int i = 0; + int instances = 0; + int cy_poll_instances = 0; + int cy_irq_instances = 0; + int dc_instances = 0; + int def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL; + int def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ; + int def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC; + int cpus = num_online_cpus(); + + instances = GET_MAX_BANKS(accel_dev); + if (!instances) + return EFAULT; + + if (accel_dev->is_vf) { + def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL_VF; + def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ_VF; + def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC_VF; + } + + /* Get the mode enabled by user */ + ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC); + + if (dc_enabled) { + if (instances >= def_dc_inst) { + dc_instances = def_dc_inst; + instances -= dc_instances; + } else { + return EFAULT; + } + } + + if (asym_enabled || sym_enabled) { + if (instances >= def_cy_poll_inst) { + cy_poll_instances = def_cy_poll_inst; + instances -= cy_poll_instances; + } else { + return EFAULT; + } + + if (sym_enabled) { + if (instances >= def_cy_irq_inst) { + cy_irq_instances = def_cy_irq_inst; + instances -= cy_irq_instances; + } else { + return EFAULT; + } + } + } + + val = (cy_poll_instances + cy_irq_instances); + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = dc_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + for (i = 0; i < (cy_irq_instances); i++) { + val = (accel_dev->accel_id * cy_irq_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_IRQ; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances); + i++) { + val = (accel_dev->accel_id * cy_poll_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = 0; i < dc_instances; i++) { + val = (accel_dev->accel_id * dc_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + return ret; +} + static int adf_cfg_static_conf(struct adf_accel_dev *accel_dev) { @@ -708,40 +951,69 @@ adf_cfg_static_conf(struct adf_accel_dev *accel_dev) unsigned long val = 0; char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; - int cpus; - int instances = 0; - int cy_poll_instances; - int cy_irq_instances; - int dc_instances; - int i = 0; + char *token, *cur_str; + int ks_enabled = 0; + int us_enabled = 0; + int asym_enabled = 0; + int sym_enabled = 0; + int cy_enabled = 0; + int dc_enabled = 0; - cpus = num_online_cpus(); - instances = - GET_MAX_BANKS(accel_dev) > cpus ? GET_MAX_BANKS(accel_dev) : cpus; - if (!instances) - return EFAULT; + strncpy(value, accel_dev->cfg->cfg_mode, ADF_CFG_MAX_VAL); + cur_str = value; - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_DC) - dc_instances = ADF_CFG_STATIC_CONF_INST_NUM_DC; - else - return EFAULT; - instances -= dc_instances; + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + while (token) { + if (!strncmp(token, ADF_CFG_KERNEL, strlen(ADF_CFG_KERNEL))) + ks_enabled = 1; + if (!strncmp(token, ADF_CFG_USER, strlen(ADF_CFG_USER))) + us_enabled = 1; + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + } - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL) - cy_poll_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL; - else - return EFAULT; - instances -= cy_poll_instances; + /* Get the services enabled by user */ + strncpy(value, accel_dev->cfg->cfg_services, ADF_CFG_MAX_VAL); + cur_str = value; - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ) - cy_irq_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ; - else - return EFAULT; - instances -= cy_irq_instances; + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + while (token) { + if (!strncmp(token, ADF_CFG_SYM, strlen(ADF_CFG_SYM))) { + sym_enabled = 1; + } + if (!strncmp(token, ADF_CFG_ASYM, strlen(ADF_CFG_ASYM))) { + asym_enabled = 1; + } + /* cy means both asym & crypto should be enabled + * Hardware resources allocation check will be done later + */ + if (!strncmp(token, ADF_CFG_CY, strlen(ADF_CFG_CY))) { + asym_enabled = 1; + sym_enabled = 1; + } + if (!strncmp(token, ADF_SERVICE_DC, strlen(ADF_SERVICE_DC))) { + dc_enabled = 1; + } + + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + } + + if (asym_enabled || sym_enabled) { + cy_enabled = 1; + } ret |= adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC); + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED); - ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC); + if (strcmp(ADF_CFG_SYM_ASYM, accel_dev->cfg->cfg_services) == 0) { + strncpy(value, ADF_CFG_CY, ADF_CFG_MAX_VAL_LEN_IN_BYTES); + } else { + strncpy(value, + accel_dev->cfg->cfg_services, + ADF_CFG_MAX_VAL_LEN_IN_BYTES); + } + + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR); val = ADF_CFG_STATIC_CONF_VER; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CONFIG_VERSION); @@ -769,6 +1041,15 @@ adf_cfg_static_conf(struct adf_accel_dev *accel_dev) return EFAULT; } + /* User defined adjustement basing on serives enabled */ + if (cy_enabled && !dc_enabled) { + cy_au += dc_au; + dc_au = 0; + } else if (!cy_enabled && dc_enabled) { + dc_au += cy_au; + cy_au = 0; + } + val = cy_au; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, @@ -806,22 +1087,6 @@ adf_cfg_static_conf(struct adf_accel_dev *accel_dev) ret |= adf_cfg_add_key_value_param( accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC); - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED); - if ((cy_poll_instances + cy_irq_instances) == 0 && dc_instances > 0) { - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_DC); - } else if (((cy_poll_instances + cy_irq_instances)) > 0 && - dc_instances == 0) { - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_SYM); - } else { - snprintf(value, - ADF_CFG_MAX_VAL_LEN_IN_BYTES, - "%s;%s", - ADF_CFG_SYM, - ADF_CFG_DC); - } - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR); - val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DC); ret |= adf_cfg_add_key_value_param( @@ -877,97 +1142,20 @@ adf_cfg_static_conf(struct adf_accel_dev *accel_dev) ret |= adf_cfg_add_key_value_param( accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC); - val = (cy_poll_instances + cy_irq_instances); - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = dc_instances; - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - for (i = 0; i < (cy_irq_instances); i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_IRQ; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + if (ks_enabled) { + ret |= adf_cfg_static_conf_kernel(accel_dev, + asym_enabled, + sym_enabled, + dc_enabled); } - for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances); - i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_POLL; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); - } - - for (i = 0; i < dc_instances; i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_POLL; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + if (us_enabled) { + ret |= + adf_cfg_static_conf_user(accel_dev, cy_enabled, dc_enabled); } if (ret) - ret = EFAULT; + ret = ENXIO; return ret; } diff --git a/sys/dev/qat/qat_common/adf_cfg_sysctl.c b/sys/dev/qat/qat_common/adf_cfg_sysctl.c new file mode 100644 index 000000000000..a0d45300d505 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_cfg_sysctl.c @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_cfg.h" +#include "adf_cfg_sysctl.h" +#include "adf_cfg_device.h" +#include "adf_common_drv.h" +#include +#include + +#define ADF_CFG_SYSCTL_BUF_SZ ADF_CFG_MAX_VAL +#define ADF_CFG_UP_STR "up" +#define ADF_CFG_DOWN_STR "down" + +#define ADF_CFG_MAX_USER_PROCESSES 64 + +static int +adf_cfg_down(struct adf_accel_dev *accel_dev) +{ + int ret = 0; + + if (!adf_dev_started(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Device qat_dev%d already down\n", + accel_dev->accel_id); + return 0; + } + + if (adf_dev_in_use(accel_dev)) { + pr_err("QAT: Device %d in use\n", accel_dev->accel_id); + goto out; + } + + if (adf_dev_stop(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Failed to stop qat_dev%d\n", + accel_dev->accel_id); + ret = EFAULT; + goto out; + } + + adf_dev_shutdown(accel_dev); + +out: + return ret; +} + +static int +adf_cfg_up(struct adf_accel_dev *accel_dev) +{ + int ret; + + if (adf_dev_started(accel_dev)) + return 0; + + if (NULL == accel_dev->hw_device->config_device) + return ENXIO; + + ret = accel_dev->hw_device->config_device(accel_dev); + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to start qat_dev%d\n", + accel_dev->accel_id); + return ret; + } + + ret = adf_dev_init(accel_dev); + if (!ret) + ret = adf_dev_start(accel_dev); + + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to start qat_dev%d\n", + accel_dev->accel_id); + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); + } + + if (!ret) { + struct adf_cfg_device *cfg_dev = NULL; + + cfg_dev = accel_dev->cfg->dev; + adf_cfg_device_clear(cfg_dev, accel_dev); + free(cfg_dev, M_QAT); + accel_dev->cfg->dev = NULL; + } + + return 0; +} + +static const char *const cfg_serv[] = + { "sym;asym", "sym", "asym", "dc", "sym;dc", "asym;dc", "cy", "cy;dc" }; + +static const char *const cfg_mode[] = { "ks;us", "us", "ks" }; + +static int adf_cfg_sysctl_services_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ]; + unsigned int len; + int ret = 0; + int i = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + strlcpy(buf, dev_cfg_data->cfg_services, sizeof(buf)); + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + /* Handle config change */ + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EINVAL; + } + + len = strlen(buf); + + for (i = 0; i < ARRAY_SIZE(cfg_serv); i++) { + if ((len > 0 && strncasecmp(cfg_serv[i], buf, len) == 0)) { + strlcpy(dev_cfg_data->cfg_services, + buf, + ADF_CFG_MAX_VAL); + break; + } + } + + if (i == ARRAY_SIZE(cfg_serv)) { + device_printf(GET_DEV(accel_dev), + "Unknown service configuration\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_mode_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ]; + unsigned int len; + int ret = 0; + int i = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + strlcpy(buf, dev_cfg_data->cfg_mode, sizeof(buf)); + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + /* Handle config change */ + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EBUSY; + } + + len = strlen(buf); + + for (i = 0; i < ARRAY_SIZE(cfg_mode); i++) { + if ((len > 0 && strncasecmp(cfg_mode[i], buf, len) == 0)) { + strlcpy(dev_cfg_data->cfg_mode, buf, ADF_CFG_MAX_VAL); + break; + } + } + + if (i == ARRAY_SIZE(cfg_mode)) { + device_printf(GET_DEV(accel_dev), + "Unknown configuration mode\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ] = { 0 }; + unsigned int len; + int ret = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + if (adf_dev_started(accel_dev)) { + strlcpy(buf, ADF_CFG_UP_STR, sizeof(buf)); + } else { + strlcpy(buf, ADF_CFG_DOWN_STR, sizeof(buf)); + } + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + len = strlen(buf); + + if ((len > 0 && strncasecmp(ADF_CFG_UP_STR, buf, len) == 0)) { + ret = adf_cfg_up(accel_dev); + + } else if (len > 0 && strncasecmp(ADF_CFG_DOWN_STR, buf, len) == 0) { + ret = adf_cfg_down(accel_dev); + + } else { + device_printf(GET_DEV(accel_dev), "QAT: Invalid operation\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_num_processes_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + uint32_t num_user_processes = 0; + int ret = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + num_user_processes = dev_cfg_data->num_user_processes; + + ret = sysctl_handle_int(oidp, &num_user_processes, 0, req); + if (ret != 0 || req->newptr == NULL) + return ret; + + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EBUSY; + } + + if (num_user_processes > ADF_CFG_MAX_USER_PROCESSES) { + return EINVAL; + } + + dev_cfg_data->num_user_processes = num_user_processes; + + return ret; +} + +int +adf_cfg_sysctl_add(struct adf_accel_dev *accel_dev) +{ + struct sysctl_ctx_list *qat_sysctl_ctx; + struct sysctl_oid *qat_sysctl_tree; + + if (!accel_dev) + return EINVAL; + + qat_sysctl_ctx = + device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev); + qat_sysctl_tree = + device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "state", + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_handle, + "A", + "QAT State"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "cfg_services", + CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_services_handle, + "A", + "QAT services confguration"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "cfg_mode", + CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_mode_handle, + "A", + "QAT mode configuration"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "num_user_processes", + CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_num_processes_handle, + "I", + "QAT user processes number "); + + return 0; +} + +void +adf_cfg_sysctl_remove(struct adf_accel_dev *accel_dev) +{ +} diff --git a/sys/dev/qat/qat_common/adf_ctl_drv.c b/sys/dev/qat/qat_common/adf_ctl_drv.c new file mode 100644 index 000000000000..8fcc3f389eee --- /dev/null +++ b/sys/dev/qat/qat_common/adf_ctl_drv.c @@ -0,0 +1,491 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_cfg.h" +#include "adf_cfg_common.h" +#include "adf_cfg_user.h" +#include "adf_heartbeat.h" +#include "adf_cfg_device.h" + +#define DEVICE_NAME "qat_adf_ctl" + +static struct sx adf_ctl_lock; + +static d_ioctl_t adf_ctl_ioctl; + +void *misc_counter; + +static struct cdevsw adf_ctl_cdevsw = { + .d_version = D_VERSION, + .d_ioctl = adf_ctl_ioctl, + .d_name = DEVICE_NAME, +}; + +static struct cdev *adf_ctl_dev; + +static void adf_chr_drv_destroy(void) +{ + destroy_dev(adf_ctl_dev); +} + +struct adf_user_addr_info { + struct list_head list; + void *user_addr; +}; + +static int adf_chr_drv_create(void) +{ + adf_ctl_dev = make_dev(&adf_ctl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + DEVICE_NAME); + + if (!adf_ctl_dev) { + printf("QAT: failed to create device\n"); + goto err_cdev_del; + } + return 0; +err_cdev_del: + return EFAULT; +} + +static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data, + caddr_t arg) +{ + *ctl_data = (struct adf_user_cfg_ctl_data *)arg; + return 0; +} + +static int adf_copy_keyval_to_user(struct adf_accel_dev *accel_dev, + struct adf_user_cfg_ctl_data *ctl_data) +{ + struct adf_user_cfg_key_val key_val; + struct adf_user_cfg_section section; + char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; + char *user_ptr; + + if (copyin(ctl_data->config_section, §ion, + sizeof(struct adf_user_cfg_section))) { + device_printf(GET_DEV(accel_dev), + "failed to copy section info\n"); + return EFAULT; + } + + if (copyin(section.params, &key_val, + sizeof(struct adf_user_cfg_key_val))) { + device_printf(GET_DEV(accel_dev), "failed to copy key val\n"); + return EFAULT; + } + + user_ptr = ((char *)section.params) + ADF_CFG_MAX_KEY_LEN_IN_BYTES; + + if (adf_cfg_get_param_value( + accel_dev, section.name, key_val.key, val)) { + return EFAULT; + } + + if (copyout(val, user_ptr, + ADF_CFG_MAX_VAL_LEN_IN_BYTES)) { + device_printf(GET_DEV(accel_dev), + "failed to copy keyvalue to user!\n"); + return EFAULT; + } + + return 0; +} + +static int adf_ctl_ioctl_get_num_devices(unsigned int cmd, + caddr_t arg) +{ + adf_devmgr_get_num_dev((uint32_t *)arg); + + return 0; +} + +static int adf_ctl_ioctl_get_status(unsigned int cmd, + caddr_t arg) +{ + struct adf_hw_device_data *hw_data; + struct adf_dev_status_info *dev_info; + struct adf_accel_dev *accel_dev; + + dev_info = (struct adf_dev_status_info *)arg; + + accel_dev = adf_devmgr_get_dev_by_id(dev_info->accel_id); + if (!accel_dev) + return ENODEV; + + hw_data = accel_dev->hw_device; + dev_info->state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN; + dev_info->num_ae = hw_data->get_num_aes(hw_data); + dev_info->num_accel = hw_data->get_num_accels(hw_data); + dev_info->num_logical_accel = hw_data->num_logical_accel; + dev_info->banks_per_accel = hw_data->num_banks + / hw_data->num_logical_accel; + strlcpy(dev_info->name, hw_data->dev_class->name, + sizeof(dev_info->name)); + dev_info->instance_id = hw_data->instance_id; + dev_info->type = hw_data->dev_class->type; + dev_info->bus = pci_get_bus(accel_to_pci_dev(accel_dev)); + dev_info->dev = pci_get_slot(accel_to_pci_dev(accel_dev)); + dev_info->fun = pci_get_function(accel_to_pci_dev(accel_dev)); + dev_info->domain = pci_get_domain(accel_to_pci_dev(accel_dev)); + + dev_info->pci_device_id = pci_get_device(accel_to_pci_dev(accel_dev)); + + dev_info->node_id = accel_dev->accel_pci_dev.node; + dev_info->sku = accel_dev->accel_pci_dev.sku; + + dev_info->device_mem_available = accel_dev->aram_info ? + accel_dev->aram_info->inter_buff_aram_region_size : 0; + + return 0; +} + +static int adf_ctl_ioctl_heartbeat(unsigned int cmd, + caddr_t arg) +{ + int ret = 0; + struct adf_accel_dev *accel_dev; + struct adf_dev_heartbeat_status_ctl *hb_status; + + hb_status = (struct adf_dev_heartbeat_status_ctl *)arg; + + accel_dev = adf_devmgr_get_dev_by_id(hb_status->device_id); + if (!accel_dev) + return ENODEV; + + if (adf_heartbeat_status(accel_dev, &hb_status->status)) { + device_printf(GET_DEV(accel_dev), + "failed to get heartbeat status\n"); + return EAGAIN; + } + return ret; +} + +static int adf_ctl_ioctl_dev_get_value(unsigned int cmd, + caddr_t arg) +{ + int ret = 0; + struct adf_user_cfg_ctl_data *ctl_data; + struct adf_accel_dev *accel_dev; + + ret = adf_ctl_alloc_resources(&ctl_data, arg); + if (ret) + return ret; + + accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id); + if (!accel_dev) { + printf("QAT: Device %d not found\n", ctl_data->device_id); + ret = ENODEV; + goto out; + } + + ret = adf_copy_keyval_to_user(accel_dev, ctl_data); + if (ret) { + ret = ENODEV; + goto out; + } +out: + return ret; +} + +static struct adf_uio_control_bundle + *adf_ctl_ioctl_bundle(struct adf_user_reserve_ring reserve) +{ + struct adf_accel_dev *accel_dev; + struct adf_uio_control_accel *accel; + struct adf_uio_control_bundle *bundle = NULL; + u8 num_rings_per_bank = 0; + + accel_dev = adf_devmgr_get_dev_by_id(reserve.accel_id); + if (!accel_dev) { + pr_err("QAT: Failed to get accel_dev\n"); + return NULL; + } + num_rings_per_bank = accel_dev->hw_device->num_rings_per_bank; + + accel = accel_dev->accel; + if (!accel) { + pr_err("QAT: Failed to get accel\n"); + return NULL; + } + + if (reserve.bank_nr >= GET_MAX_BANKS(accel_dev)) { + pr_err("QAT: Invalid bank number %d\n", reserve.bank_nr); + return NULL; + } + if (reserve.ring_mask & ~((1 << num_rings_per_bank) - 1)) { + pr_err("QAT: Invalid ring mask %0X\n", reserve.ring_mask); + return NULL; + } + if (accel->num_ker_bundles > reserve.bank_nr) { + pr_err("QAT: Invalid user reserved bank\n"); + return NULL; + } + bundle = &accel->bundle[reserve.bank_nr]; + + return bundle; +} + +static int adf_ctl_ioctl_reserve_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve = {0}; + struct adf_uio_control_bundle *bundle; + struct adf_uio_instance_rings *instance_rings; + int pid_entry_found = 0; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + if (bundle->rings_used & reserve.ring_mask) { + pr_err("QAT: Bundle %d, rings 0x%04X already reserved\n", + reserve.bank_nr, + reserve.ring_mask); + mutex_unlock(&bundle->lock); + return -EINVAL; + } + mutex_unlock(&bundle->lock); + + /* Find the list entry for this process */ + mutex_lock(&bundle->list_lock); + list_for_each_entry(instance_rings, &bundle->list, list) { + if (instance_rings->user_pid == curproc->p_pid) { + pid_entry_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (!pid_entry_found) { + pr_err("QAT: process %d not found\n", curproc->p_pid); + return -EINVAL; + } + + instance_rings->ring_mask |= reserve.ring_mask; + mutex_lock(&bundle->lock); + bundle->rings_used |= reserve.ring_mask; + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_release_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + struct adf_uio_instance_rings *instance_rings; + int pid_entry_found; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + /* Find the list entry for this process */ + pid_entry_found = 0; + mutex_lock(&bundle->list_lock); + list_for_each_entry(instance_rings, &bundle->list, list) { + if (instance_rings->user_pid == curproc->p_pid) { + pid_entry_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (!pid_entry_found) { + pr_err("QAT: No ring reservation found for PID %d\n", + curproc->p_pid); + return -EINVAL; + } + + if ((instance_rings->ring_mask & reserve.ring_mask) != + reserve.ring_mask) { + pr_err("QAT: Attempt to release rings not reserved by this process\n"); + return -EINVAL; + } + + instance_rings->ring_mask &= ~reserve.ring_mask; + mutex_lock(&bundle->lock); + bundle->rings_used &= ~reserve.ring_mask; + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_enable_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + bundle->rings_enabled |= reserve.ring_mask; + adf_update_uio_ring_arb(bundle); + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_disable_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + bundle->rings_enabled &= ~reserve.ring_mask; + adf_update_uio_ring_arb(bundle); + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl(struct cdev *dev, + u_long cmd, + caddr_t arg, + int fflag, + struct thread *td) +{ + int ret = 0; + bool allowed = false; + int i; + static const unsigned int unrestricted_cmds[] = { + IOCTL_GET_NUM_DEVICES, IOCTL_STATUS_ACCEL_DEV, + IOCTL_HEARTBEAT_ACCEL_DEV, IOCTL_GET_CFG_VAL, + IOCTL_RESERVE_RING, IOCTL_RELEASE_RING, + IOCTL_ENABLE_RING, IOCTL_DISABLE_RING, + }; + + if (priv_check(curthread, PRIV_DRIVER)) { + for (i = 0; i < ARRAY_SIZE(unrestricted_cmds); i++) { + if (cmd == unrestricted_cmds[i]) { + allowed = true; + break; + } + } + if (!allowed) + return EACCES; + } + + /* All commands have an argument */ + if (!arg) + return EFAULT; + + if (sx_xlock_sig(&adf_ctl_lock)) + return EINTR; + + switch (cmd) { + case IOCTL_GET_NUM_DEVICES: + ret = adf_ctl_ioctl_get_num_devices(cmd, arg); + break; + case IOCTL_STATUS_ACCEL_DEV: + ret = adf_ctl_ioctl_get_status(cmd, arg); + break; + case IOCTL_GET_CFG_VAL: + ret = adf_ctl_ioctl_dev_get_value(cmd, arg); + break; + case IOCTL_RESERVE_RING: + ret = adf_ctl_ioctl_reserve_ring(arg); + break; + case IOCTL_RELEASE_RING: + ret = adf_ctl_ioctl_release_ring(arg); + break; + case IOCTL_ENABLE_RING: + ret = adf_ctl_ioctl_enable_ring(arg); + break; + case IOCTL_DISABLE_RING: + ret = adf_ctl_ioctl_disable_ring(arg); + break; + case IOCTL_HEARTBEAT_ACCEL_DEV: + ret = adf_ctl_ioctl_heartbeat(cmd, arg); + break; + default: + printf("QAT: Invalid ioctl\n"); + ret = ENOTTY; + break; + } + sx_xunlock(&adf_ctl_lock); + return ret; +} + +int +adf_register_ctl_device_driver(void) +{ + sx_init(&adf_ctl_lock, "adf ctl"); + + if (adf_chr_drv_create()) + goto err_chr_dev; + + adf_state_init(); + if (adf_processes_dev_register() != 0) + goto err_processes_dev_register; + return 0; + +err_processes_dev_register: + adf_chr_drv_destroy(); +err_chr_dev: + sx_destroy(&adf_ctl_lock); + return EFAULT; +} + +void +adf_unregister_ctl_device_driver(void) +{ + adf_processes_dev_unregister(); + adf_state_destroy(); + adf_chr_drv_destroy(); + adf_clean_vf_map(false); + sx_destroy(&adf_ctl_lock); +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c new file mode 100644 index 000000000000..e66abaa28ad1 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c @@ -0,0 +1,677 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" + +#define ADF_DEV_PROCESSES_NAME "qat_dev_processes" +#define ADF_DEV_STATE_NAME "qat_dev_state" + +#define ADF_STATE_CALLOUT_TIME 10 + +static const char *mtx_name = "state_callout_mtx"; + +static d_open_t adf_processes_open; +static void adf_processes_release(void *data); +static d_read_t adf_processes_read; +static d_write_t adf_processes_write; + +static d_open_t adf_state_open; +static void adf_state_release(void *data); +static d_read_t adf_state_read; +static int adf_state_kqfilter(struct cdev *dev, struct knote *kn); +static int adf_state_kqread_event(struct knote *kn, long hint); +static void adf_state_kqread_detach(struct knote *kn); + +static struct callout callout; +static struct mtx mtx; +static struct service_hndl adf_state_hndl; + +struct entry_proc_events { + struct adf_state_priv_data *proc_events; + + SLIST_ENTRY(entry_proc_events) entries_proc_events; +}; + +struct entry_state { + struct adf_state state; + + STAILQ_ENTRY(entry_state) entries_state; +}; + +SLIST_HEAD(proc_events_head, entry_proc_events); +STAILQ_HEAD(state_head, entry_state); + +static struct proc_events_head proc_events_head; + +struct adf_processes_priv_data { + char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES]; + int read_flag; + struct list_head list; +}; + +struct adf_state_priv_data { + struct cdev *cdev; + struct selinfo rsel; + struct state_head state_head; +}; + +static struct cdevsw adf_processes_cdevsw = { + .d_version = D_VERSION, + .d_open = adf_processes_open, + .d_read = adf_processes_read, + .d_write = adf_processes_write, + .d_name = ADF_DEV_PROCESSES_NAME, +}; + +static struct cdevsw adf_state_cdevsw = { + .d_version = D_VERSION, + .d_open = adf_state_open, + .d_read = adf_state_read, + .d_kqfilter = adf_state_kqfilter, + .d_name = ADF_DEV_STATE_NAME, +}; + +static struct filterops adf_state_read_filterops = { + .f_isfd = 1, + .f_attach = NULL, + .f_detach = adf_state_kqread_detach, + .f_event = adf_state_kqread_event, +}; + +static struct cdev *adf_processes_dev; +static struct cdev *adf_state_dev; + +static LINUX_LIST_HEAD(processes_list); + +struct sx processes_list_sema; +SX_SYSINIT(processes_list_sema, &processes_list_sema, "adf proc list"); + +static void +adf_chr_drv_destroy(void) +{ + destroy_dev(adf_processes_dev); +} + +static int +adf_chr_drv_create(void) +{ + + adf_processes_dev = make_dev(&adf_processes_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + ADF_DEV_PROCESSES_NAME); + if (adf_processes_dev == NULL) { + printf("QAT: failed to create device\n"); + goto err_cdev_del; + } + return 0; +err_cdev_del: + return EFAULT; +} + +static int +adf_processes_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + int i = 0, devices = 0; + struct adf_accel_dev *accel_dev = NULL; + struct adf_processes_priv_data *prv_data = NULL; + int error = 0; + + for (i = 0; i < ADF_MAX_DEVICES; i++) { + accel_dev = adf_devmgr_get_dev_by_id(i); + if (!accel_dev) + continue; + if (!adf_dev_started(accel_dev)) + continue; + devices++; + } + if (!devices) { + printf("QAT: No active devices found.\n"); + return ENXIO; + } + prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); + if (!prv_data) + return ENOMEM; + INIT_LIST_HEAD(&prv_data->list); + error = devfs_set_cdevpriv(prv_data, adf_processes_release); + if (error) { + free(prv_data, M_QAT); + return error; + } + + return 0; +} + +static int +adf_get_first_started_dev(void) +{ + int i = 0; + struct adf_accel_dev *accel_dev = NULL; + + for (i = 0; i < ADF_MAX_DEVICES; i++) { + accel_dev = adf_devmgr_get_dev_by_id(i); + if (!accel_dev) + continue; + if (adf_dev_started(accel_dev)) + return i; + } + + return -1; +} + +static int +adf_processes_write(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct adf_processes_priv_data *prv_data = NULL; + struct adf_processes_priv_data *pdata = NULL; + int dev_num = 0, pr_num = 0; + struct list_head *lpos = NULL; + char usr_name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES] = { 0 }; + struct adf_accel_dev *accel_dev = NULL; + struct adf_cfg_section *section_ptr = NULL; + bool pr_name_available = 1; + uint32_t num_accel_devs = 0; + int error = 0; + ssize_t count; + int dev_id; + + error = devfs_get_cdevpriv((void **)&prv_data); + if (error) { + printf("QAT: invalid file descriptor\n"); + return error; + } + + if (prv_data->read_flag == 1) { + printf("QAT: can only write once\n"); + return EBADF; + } + count = uio->uio_resid; + if ((count <= 0) || (count > ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) { + printf("QAT: wrong size %d\n", (int)count); + return EIO; + } + + error = uiomove(usr_name, count, uio); + if (error) { + printf("QAT: can't copy data\n"); + return error; + } + + /* Lock other processes and try to find out the process name */ + if (sx_xlock_sig(&processes_list_sema)) { + printf("QAT: can't aquire process info lock\n"); + return EBADF; + } + + dev_id = adf_get_first_started_dev(); + if (-1 == dev_id) { + pr_err("QAT: could not find started device\n"); + sx_xunlock(&processes_list_sema); + return -EIO; + } + + accel_dev = adf_devmgr_get_dev_by_id(dev_id); + if (!accel_dev) { + pr_err("QAT: could not find started device\n"); + sx_xunlock(&processes_list_sema); + return -EIO; + } + + /* If there is nothing there then take the first name and return */ + if (list_empty(&processes_list)) { + snprintf(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES, + "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d", + usr_name, + 0); + list_add(&prv_data->list, &processes_list); + sx_xunlock(&processes_list_sema); + prv_data->read_flag = 1; + return 0; + } + + /* If there are processes running then search for a first free name */ + adf_devmgr_get_num_dev(&num_accel_devs); + for (dev_num = 0; dev_num < num_accel_devs; dev_num++) { + accel_dev = adf_devmgr_get_dev_by_id(dev_num); + if (!accel_dev) + continue; + + if (!adf_dev_started(accel_dev)) + continue; /* to next device */ + + for (pr_num = 0; pr_num < GET_MAX_PROCESSES(accel_dev); + pr_num++) { + snprintf(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES, + "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d", + usr_name, + pr_num); + pr_name_available = 1; + /* Figure out if section exists in the config table */ + section_ptr = + adf_cfg_sec_find(accel_dev, prv_data->name); + if (NULL == section_ptr) { + /* This section name doesn't exist */ + pr_name_available = 0; + /* As process_num enumerates from 0, once we get + * to one which doesn't exist no further ones + * will exist. On to next device + */ + break; + } + /* Figure out if it's been taken already */ + list_for_each(lpos, &processes_list) + { + pdata = + list_entry(lpos, + struct adf_processes_priv_data, + list); + if (!strncmp( + pdata->name, + prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) { + pr_name_available = 0; + break; + } + } + if (pr_name_available) + break; + } + if (pr_name_available) + break; + } + /* + * If we have a valid name that is not on + * the list take it and add to the list + */ + if (pr_name_available) { + list_add(&prv_data->list, &processes_list); + sx_xunlock(&processes_list_sema); + prv_data->read_flag = 1; + return 0; + } + /* If not then the process needs to wait */ + sx_xunlock(&processes_list_sema); + explicit_bzero(prv_data->name, ADF_CFG_MAX_SECTION_LEN_IN_BYTES); + prv_data->read_flag = 0; + return 1; +} + +static int +adf_processes_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct adf_processes_priv_data *prv_data = NULL; + int error = 0; + + error = devfs_get_cdevpriv((void **)&prv_data); + if (error) { + printf("QAT: invalid file descriptor\n"); + return error; + } + + /* + * If there is a name that the process can use then give it + * to the proocess. + */ + if (prv_data->read_flag) { + error = uiomove(prv_data->name, + strnlen(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES), + uio); + if (error) { + printf("QAT: failed to copy data to user\n"); + return error; + } + return 0; + } + + return EIO; +} + +static void +adf_processes_release(void *data) +{ + struct adf_processes_priv_data *prv_data = NULL; + + prv_data = (struct adf_processes_priv_data *)data; + sx_xlock(&processes_list_sema); + list_del(&prv_data->list); + sx_xunlock(&processes_list_sema); + free(prv_data, M_QAT); +} + +int +adf_processes_dev_register(void) +{ + return adf_chr_drv_create(); +} + +void +adf_processes_dev_unregister(void) +{ + adf_chr_drv_destroy(); +} + +static void +adf_state_callout_notify_ev(void *arg) +{ + int notified = 0; + struct adf_state_priv_data *priv = NULL; + struct entry_proc_events *proc_events = NULL; + + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) { + notified = 1; + priv = proc_events->proc_events; + wakeup(priv); + selwakeup(&priv->rsel); + KNOTE_UNLOCKED(&priv->rsel.si_note, 0); + } + } + if (notified) + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); +} + +static void +adf_state_set(int dev, enum adf_event event) +{ + struct adf_accel_dev *accel_dev = NULL; + struct state_head *head = NULL; + struct entry_proc_events *proc_events = NULL; + struct entry_state *state = NULL; + + accel_dev = adf_devmgr_get_dev_by_id(dev); + if (!accel_dev) + return; + mtx_lock(&mtx); + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + state = NULL; + head = &proc_events->proc_events->state_head; + state = malloc(sizeof(struct entry_state), + M_QAT, + M_NOWAIT | M_ZERO); + if (!state) + continue; + state->state.dev_state = event; + state->state.dev_id = dev; + STAILQ_INSERT_TAIL(head, state, entries_state); + if (event == ADF_EVENT_STOP) { + state = NULL; + state = malloc(sizeof(struct entry_state), + M_QAT, + M_NOWAIT | M_ZERO); + if (!state) + continue; + state->state.dev_state = ADF_EVENT_SHUTDOWN; + state->state.dev_id = dev; + STAILQ_INSERT_TAIL(head, state, entries_state); + } + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); +} + +static int +adf_state_event_handler(struct adf_accel_dev *accel_dev, enum adf_event event) +{ + int ret = 0; + +#if defined(QAT_UIO) && defined(QAT_DBG) + if (event > ADF_EVENT_DBG_SHUTDOWN) + return -EINVAL; +#else + if (event > ADF_EVENT_ERROR) + return -EINVAL; +#endif /* defined(QAT_UIO) && defined(QAT_DBG) */ + + switch (event) { + case ADF_EVENT_INIT: + return ret; + case ADF_EVENT_SHUTDOWN: + return ret; + case ADF_EVENT_RESTARTING: + break; + case ADF_EVENT_RESTARTED: + break; + case ADF_EVENT_START: + return ret; + case ADF_EVENT_STOP: + break; + case ADF_EVENT_ERROR: + break; +#if defined(QAT_UIO) && defined(QAT_DBG) + case ADF_EVENT_PROC_CRASH: + break; + case ADF_EVENT_MANUAL_DUMP: + break; + case ADF_EVENT_SLICE_HANG: + break; + case ADF_EVENT_DBG_SHUTDOWN: + break; +#endif /* defined(QAT_UIO) && defined(QAT_DBG) */ + default: + return -1; + } + + adf_state_set(accel_dev->accel_id, event); + + return 0; +} + +static int +adf_state_kqfilter(struct cdev *dev, struct knote *kn) +{ + struct adf_state_priv_data *priv; + + mtx_lock(&mtx); + priv = dev->si_drv1; + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &adf_state_read_filterops; + kn->kn_hook = priv; + knlist_add(&priv->rsel.si_note, kn, 0); + mtx_unlock(&mtx); + return 0; + default: + mtx_unlock(&mtx); + return -EINVAL; + } +} + +static int +adf_state_kqread_event(struct knote *kn, long hint) +{ + return 1; +} + +static void +adf_state_kqread_detach(struct knote *kn) +{ + struct adf_state_priv_data *priv = NULL; + + mtx_lock(&mtx); + if (!kn) { + mtx_unlock(&mtx); + return; + } + priv = kn->kn_hook; + if (!priv) { + mtx_unlock(&mtx); + return; + } + knlist_remove(&priv->rsel.si_note, kn, 1); + mtx_unlock(&mtx); +} + +void +adf_state_init(void) +{ + adf_state_dev = make_dev(&adf_state_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + "%s", + ADF_DEV_STATE_NAME); + SLIST_INIT(&proc_events_head); + mtx_init(&mtx, mtx_name, NULL, MTX_DEF); + callout_init_mtx(&callout, &mtx, 0); + explicit_bzero(&adf_state_hndl, sizeof(adf_state_hndl)); + adf_state_hndl.event_hld = adf_state_event_handler; + adf_state_hndl.name = "adf_state_event_handler"; + mtx_lock(&mtx); + adf_service_register(&adf_state_hndl); + callout_reset(&callout, + ADF_STATE_CALLOUT_TIME, + adf_state_callout_notify_ev, + NULL); + mtx_unlock(&mtx); +} + +void +adf_state_destroy(void) +{ + struct entry_proc_events *proc_events = NULL; + + mtx_lock(&mtx); + adf_service_unregister(&adf_state_hndl); + callout_stop(&callout); + while (!SLIST_EMPTY(&proc_events_head)) { + proc_events = SLIST_FIRST(&proc_events_head); + SLIST_REMOVE_HEAD(&proc_events_head, entries_proc_events); + free(proc_events, M_QAT); + } + destroy_dev(adf_state_dev); + mtx_unlock(&mtx); + mtx_destroy(&mtx); +} + +static int +adf_state_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct adf_state_priv_data *prv_data = NULL; + struct entry_proc_events *entry_proc_events = NULL; + int ret = 0; + + prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); + if (!prv_data) + return -ENOMEM; + entry_proc_events = + malloc(sizeof(struct entry_proc_events), M_QAT, M_WAITOK | M_ZERO); + if (!entry_proc_events) { + free(prv_data, M_QAT); + return -ENOMEM; + } + mtx_lock(&mtx); + prv_data->cdev = dev; + prv_data->cdev->si_drv1 = prv_data; + knlist_init_mtx(&prv_data->rsel.si_note, &mtx); + STAILQ_INIT(&prv_data->state_head); + entry_proc_events->proc_events = prv_data; + SLIST_INSERT_HEAD(&proc_events_head, + entry_proc_events, + entries_proc_events); + ret = devfs_set_cdevpriv(prv_data, adf_state_release); + if (ret) { + SLIST_REMOVE(&proc_events_head, + entry_proc_events, + entry_proc_events, + entries_proc_events); + free(entry_proc_events, M_QAT); + free(prv_data, M_QAT); + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); + return ret; +} + +static int +adf_state_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + int ret = 0; + struct adf_state_priv_data *prv_data = NULL; + struct state_head *state_head = NULL; + struct entry_state *entry_state = NULL; + struct adf_state *state = NULL; + struct entry_proc_events *proc_events = NULL; + + mtx_lock(&mtx); + ret = devfs_get_cdevpriv((void **)&prv_data); + if (ret) { + mtx_unlock(&mtx); + return 0; + } + state_head = &prv_data->state_head; + if (STAILQ_EMPTY(state_head)) { + mtx_unlock(&mtx); + return 0; + } + entry_state = STAILQ_FIRST(state_head); + state = &entry_state->state; + ret = uiomove(state, sizeof(struct adf_state), uio); + if (!ret && !STAILQ_EMPTY(state_head)) { + STAILQ_REMOVE_HEAD(state_head, entries_state); + free(entry_state, M_QAT); + } + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) { + prv_data = proc_events->proc_events; + wakeup(prv_data); + selwakeup(&prv_data->rsel); + KNOTE_UNLOCKED(&prv_data->rsel.si_note, 0); + } + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); + return ret; +} + +static void +adf_state_release(void *data) +{ + struct adf_state_priv_data *prv_data = NULL; + struct entry_state *entry_state = NULL; + struct entry_proc_events *entry_proc_events = NULL; + struct entry_proc_events *tmp = NULL; + + mtx_lock(&mtx); + prv_data = (struct adf_state_priv_data *)data; + knlist_delete(&prv_data->rsel.si_note, curthread, 1); + knlist_destroy(&prv_data->rsel.si_note); + seldrain(&prv_data->rsel); + while (!STAILQ_EMPTY(&prv_data->state_head)) { + entry_state = STAILQ_FIRST(&prv_data->state_head); + STAILQ_REMOVE_HEAD(&prv_data->state_head, entries_state); + free(entry_state, M_QAT); + } + SLIST_FOREACH_SAFE (entry_proc_events, + &proc_events_head, + entries_proc_events, + tmp) { + if (entry_proc_events->proc_events == prv_data) { + SLIST_REMOVE(&proc_events_head, + entry_proc_events, + entry_proc_events, + entries_proc_events); + free(entry_proc_events, M_QAT); + } + } + free(prv_data, M_QAT); + mtx_unlock(&mtx); +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio.c b/sys/dev/qat/qat_common/adf_freebsd_uio.c new file mode 100644 index 000000000000..5c74b7e8b9b0 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_uio.c @@ -0,0 +1,450 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADF_UIO_GET_NAME(accel_dev) (GET_HW_DATA(accel_dev)->dev_class->name) +#define ADF_UIO_GET_TYPE(accel_dev) (GET_HW_DATA(accel_dev)->dev_class->type) +#define ADF_UIO_GET_BAR(accel_dev) \ + (GET_HW_DATA(accel_dev)->get_etr_bar_id(GET_HW_DATA(accel_dev))) + +static d_ioctl_t adf_uio_ioctl; +static d_mmap_single_t adf_uio_mmap_single; + +static struct cdevsw adf_uio_cdevsw = { .d_ioctl = adf_uio_ioctl, + .d_mmap_single = adf_uio_mmap_single, + .d_version = D_VERSION, + .d_name = "qat" }; + +struct adf_uio_open_bundle { + struct adf_uio_control_accel *accel; + int bundle; + struct file **mem_files; + int num_mem_files; +}; + +static void +adf_release_bundle(void *arg) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + struct adf_uio_control_bundle *bundle = NULL; + struct adf_uio_instance_rings *instance_rings, *tmp; + int i = 0; + + handle = arg; + accel = handle->accel; + bundle = &accel->bundle[handle->bundle]; + + mutex_lock(&bundle->lock); + adf_uio_do_cleanup_orphan(bundle->hardware_bundle_number, accel); + mutex_unlock(&bundle->lock); + + for (i = 0; i < handle->num_mem_files; i++) { + /* + * Similar to the garbage collection of orphaned file + * descriptor references in UNIX domain socket control + * messages, the current thread isn't relevant to the + * the file descriptor reference being released. In + * particular, the current thread does not hold any + * advisory file locks on these file descriptors. + */ + fdrop(handle->mem_files[i], NULL); + } + free(handle->mem_files, M_QAT); + + mtx_lock(&accel->lock); + + mutex_lock(&bundle->list_lock); + list_for_each_entry_safe(instance_rings, tmp, &bundle->list, list) + { + if (instance_rings->user_pid == curproc->p_pid) { + list_del(&instance_rings->list); + free(instance_rings, M_QAT); + break; + } + } + mutex_unlock(&bundle->list_lock); + + adf_dev_put(accel->accel_dev); + accel->num_handles--; + free(handle, M_QAT); + if (!accel->num_handles) { + cv_broadcast(&accel->cleanup_ok); + /* the broadcasting effect happens after releasing accel->lock + */ + } + mtx_unlock(&accel->lock); +} + +static int +adf_add_mem_fd(struct adf_accel_dev *accel_dev, int mem_fd) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + struct file *fp, **new_files; + cap_rights_t rights; + int error = -1, old_count = 0; + + error = devfs_get_cdevpriv((void **)&handle); + if (error) + return (error); + + error = fget(curthread, mem_fd, cap_rights_init(&rights), &fp); + if (error) { + printf( + "Failed to fetch file pointer from current process %d \n", + __LINE__); + return (error); + } + + accel = accel_dev->accel; + mtx_lock(&accel->lock); + for (;;) { + old_count = handle->num_mem_files; + mtx_unlock(&accel->lock); + new_files = malloc((old_count + 1) * sizeof(*new_files), + M_QAT, + M_WAITOK); + mtx_lock(&accel->lock); + if (old_count == handle->num_mem_files) { + if (old_count != 0) { + memcpy(new_files, + handle->mem_files, + old_count * sizeof(*new_files)); + free(handle->mem_files, M_QAT); + } + handle->mem_files = new_files; + new_files[old_count] = fp; + handle->num_mem_files++; + break; + } else + free(new_files, M_QAT); + } + mtx_unlock(&accel->lock); + return (0); +} + +static vm_object_t +adf_uio_map_bar(struct adf_accel_dev *accel_dev, uint8_t bank_offset) +{ + unsigned int ring_bundle_size, offset; + struct sglist *sg = NULL; + struct adf_uio_control_accel *accel = accel_dev->accel; + struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info; + vm_object_t obj; + + ring_bundle_size = csr_info->ring_bundle_size; + offset = bank_offset * ring_bundle_size; + + sg = sglist_alloc(1, M_WAITOK); + + /* Starting from new HW there is an additional offset + * for bundle CSRs + */ + sglist_append_phys(sg, + accel->bar->base_addr + offset + + csr_info->csr_addr_offset, + ring_bundle_size); + + obj = vm_pager_allocate( + OBJT_SG, sg, ring_bundle_size, VM_PROT_RW, 0, NULL); + if (obj != NULL) { + VM_OBJECT_WLOCK(obj); + vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); + VM_OBJECT_WUNLOCK(obj); + } + sglist_free(sg); + + return obj; +} + +static int +adf_alloc_bundle(struct adf_accel_dev *accel_dev, int bundle_nr) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + int error; + + if (bundle_nr < 0 || bundle_nr >= GET_MAX_BANKS(accel_dev)) { + printf("ERROR in %s (%d) %d\n", __func__, bundle_nr, __LINE__); + return EINVAL; + } + + accel = accel_dev->accel; + handle = malloc(sizeof(*handle), M_QAT, M_WAITOK | M_ZERO); + if (!handle) { + printf("ERROR in adf_alloc_bundle %d\n", __LINE__); + return ENOMEM; + } + handle->accel = accel; + handle->bundle = bundle_nr; + + mtx_lock(&accel->lock); + adf_dev_get(accel_dev); + accel->num_handles++; + mtx_unlock(&accel->lock); + + error = devfs_set_cdevpriv(handle, adf_release_bundle); + if (error) { + adf_release_bundle(handle); + device_printf(GET_DEV(accel_dev), + "ERROR in adf_alloc_bundle %d\n", + __LINE__); + return (error); + } + + return (0); +} + +static int +adf_uio_ioctl(struct cdev *dev, + u_long cmd, + caddr_t data, + int fflag, + struct thread *td) +{ + struct adf_accel_dev *accel_dev = dev->si_drv1; + struct adf_hw_csr_info *csr_info = NULL; + + if (!accel_dev) { + printf("%s - accel_dev is NULL\n", __func__); + return EFAULT; + } + + csr_info = &accel_dev->hw_device->csr_info; + + switch (cmd) { + case IOCTL_GET_BUNDLE_SIZE: + *(uint32_t *)data = csr_info->ring_bundle_size; + break; + case IOCTL_ALLOC_BUNDLE: + return (adf_alloc_bundle(accel_dev, *(int *)data)); + case IOCTL_GET_ACCEL_TYPE: + *(uint32_t *)data = ADF_UIO_GET_TYPE(accel_dev); + break; + case IOCTL_ADD_MEM_FD: + return (adf_add_mem_fd(accel_dev, *(int *)data)); + default: + return (ENOTTY); + } + return (0); +} + +static int +adf_uio_mmap_single(struct cdev *dev, + vm_ooffset_t *offset, + vm_size_t size, + struct vm_object **object, + int nprot) +{ + struct adf_uio_open_bundle *handle = NULL; + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_control_bundle *bundle = NULL; + struct adf_uio_instance_rings *instance_rings; + int error; + + error = devfs_get_cdevpriv((void **)&handle); + if (error) + return (error); + + if (!handle->accel) { + printf("QAT: Error - no accel in handle\n"); + return EINVAL; + } + accel = handle->accel; + + if (!accel->accel_dev) { + printf("QAT: Error - no accel_dev in accel\n"); + return EINVAL; + } + + bundle = &accel->bundle[handle->bundle]; + if (!bundle->obj) { + printf("QAT: Error no vm_object in bundle\n"); + return EINVAL; + } + + /* Adding pid to bundle list */ + instance_rings = + malloc(sizeof(*instance_rings), M_QAT, M_WAITOK | M_ZERO); + if (!instance_rings) { + printf("QAT: Memory allocation error - line: %d\n", __LINE__); + return -ENOMEM; + } + instance_rings->user_pid = curproc->p_pid; + instance_rings->ring_mask = 0; + mutex_lock(&bundle->list_lock); + list_add_tail(&instance_rings->list, &bundle->list); + mutex_unlock(&bundle->list_lock); + + vm_object_reference(bundle->obj); + *object = bundle->obj; + return (0); +} + +static inline void +adf_uio_init_accel_ctrl(struct adf_uio_control_accel *accel, + struct adf_accel_dev *accel_dev, + unsigned int nb_bundles) +{ + struct adf_uio_control_bundle *bundle; + struct qat_uio_bundle_dev *priv; + unsigned int i; + + accel->nb_bundles = nb_bundles; + accel->total_used_bundles = 0; + + for (i = 0; i < nb_bundles; i++) { + /*initialize the bundle */ + bundle = &accel->bundle[i]; + priv = &bundle->uio_priv; + bundle->hardware_bundle_number = + GET_MAX_BANKS(accel_dev) - nb_bundles + i; + + INIT_LIST_HEAD(&bundle->list); + priv->bundle = bundle; + priv->accel = accel; + + mutex_init(&bundle->lock); + mutex_init(&bundle->list_lock); + if (!accel->bar) + printf("ERROR: bar not defined in accel\n"); + else + bundle->csr_addr = (void *)accel->bar->virt_addr; + } +} + +/** + * Initialization bars on dev start. + */ +static inline void +adf_uio_init_bundle_dev(struct adf_uio_control_accel *accel, + struct adf_accel_dev *accel_dev, + unsigned int nb_bundles) +{ + struct adf_uio_control_bundle *bundle; + unsigned int i; + + for (i = 0; i < nb_bundles; i++) { + bundle = &accel->bundle[i]; + bundle->obj = + adf_uio_map_bar(accel_dev, bundle->hardware_bundle_number); + if (!bundle->obj) { + device_printf(GET_DEV(accel_dev), + "ERROR in adf_alloc_bundle %d\n", + __LINE__); + } + } +} + +int +adf_uio_register(struct adf_accel_dev *accel_dev) +{ + struct adf_uio_control_accel *accel = NULL; + char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; + int nb_bundles; + + if (!accel_dev) { + printf("%s - accel_dev is NULL\n", __func__); + return EFAULT; + } + + if (adf_cfg_get_param_value( + accel_dev, ADF_GENERAL_SEC, ADF_FIRST_USER_BUNDLE, val)) { + nb_bundles = 0; + } else { + nb_bundles = GET_MAX_BANKS(accel_dev); + } + + if (nb_bundles) { + accel = malloc(sizeof(*accel) + + nb_bundles * + sizeof(struct adf_uio_control_bundle), + M_QAT, + M_WAITOK | M_ZERO); + mtx_init(&accel->lock, "qat uio", NULL, MTX_DEF); + accel->accel_dev = accel_dev; + accel->bar = accel_dev->accel_pci_dev.pci_bars + + ADF_UIO_GET_BAR(accel_dev); + + adf_uio_init_accel_ctrl(accel, accel_dev, nb_bundles); + accel->cdev = make_dev(&adf_uio_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + "%s", + device_get_nameunit(GET_DEV(accel_dev))); + if (accel->cdev == NULL) { + mtx_destroy(&accel->lock); + goto fail_clean; + } + accel->cdev->si_drv1 = accel_dev; + accel_dev->accel = accel; + cv_init(&accel->cleanup_ok, "uio_accel_cv"); + + adf_uio_init_bundle_dev(accel, accel_dev, nb_bundles); + } + return 0; +fail_clean: + free(accel, M_QAT); + device_printf(GET_DEV(accel_dev), "Failed to register UIO devices\n"); + return ENODEV; +} + +void +adf_uio_remove(struct adf_accel_dev *accel_dev) +{ + struct adf_uio_control_accel *accel = accel_dev->accel; + struct adf_uio_control_bundle *bundle; + unsigned int i; + + if (accel) { + /* Un-mapping all bars */ + for (i = 0; i < accel->nb_bundles; i++) { + bundle = &accel->bundle[i]; + vm_object_deallocate(bundle->obj); + } + + destroy_dev(accel->cdev); + mtx_lock(&accel->lock); + while (accel->num_handles) { + cv_timedwait_sig(&accel->cleanup_ok, + &accel->lock, + 3 * hz); + } + mtx_unlock(&accel->lock); + mtx_destroy(&accel->lock); + cv_destroy(&accel->cleanup_ok); + free(accel, M_QAT); + accel_dev->accel = NULL; + } +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c new file mode 100644 index 000000000000..d299fde6cc0d --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c @@ -0,0 +1,404 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TX_RINGS_DISABLE 0 +#define TX_RINGS_ENABLE 1 +#define PKE_REQ_SIZE 64 +#define BASE_ADDR_SHIFT 6 +#define PKE_RX_RING_0 0 +#define PKE_RX_RING_1 1 + +#define ADF_RING_EMPTY_RETRY_DELAY 2 +#define ADF_RING_EMPTY_MAX_RETRY 15 + +struct bundle_orphan_ring { + unsigned long tx_mask; + unsigned long rx_mask; + unsigned long asym_mask; + int bank; + struct resource *csr_base; + struct adf_uio_control_bundle *bundle; +}; + +/* + * if orphan->tx_mask does not match with orphan->rx_mask + */ +static void +check_orphan_ring(struct adf_accel_dev *accel_dev, + struct bundle_orphan_ring *orphan, + struct adf_hw_device_data *hw_data) +{ + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + int i; + int tx_rx_gap = hw_data->tx_rx_gap; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + struct resource *csr_base = orphan->csr_base; + int bank = orphan->bank; + + for (i = 0; i < num_rings_per_bank; i++) { + if (test_bit(i, &orphan->tx_mask)) { + int rx_ring = i + tx_rx_gap; + + if (!test_bit(rx_ring, &orphan->rx_mask)) { + __clear_bit(i, &orphan->tx_mask); + + /* clean up this tx ring */ + csr_ops->write_csr_ring_config(csr_base, + bank, + i, + 0); + csr_ops->write_csr_ring_base(csr_base, + bank, + i, + 0); + } + + } else if (test_bit(i, &orphan->rx_mask)) { + int tx_ring = i - tx_rx_gap; + + if (!test_bit(tx_ring, &orphan->tx_mask)) { + __clear_bit(i, &orphan->rx_mask); + + /* clean up this rx ring */ + csr_ops->write_csr_ring_config(csr_base, + bank, + i, + 0); + csr_ops->write_csr_ring_base(csr_base, + bank, + i, + 0); + } + } + } +} + +static int +get_orphan_bundle(int bank, + struct adf_uio_control_accel *accel, + struct bundle_orphan_ring **orphan_bundle_out) +{ + int i; + int ret = 0; + struct resource *csr_base; + unsigned long tx_mask; + unsigned long asym_mask; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + struct bundle_orphan_ring *orphan_bundle = NULL; + uint64_t base; + struct list_head *entry; + struct adf_uio_instance_rings *instance_rings; + struct adf_uio_control_bundle *bundle; + u16 ring_mask = 0; + + orphan_bundle = + malloc(sizeof(*orphan_bundle), M_QAT, M_WAITOK | M_ZERO); + if (!orphan_bundle) + return ENOMEM; + + csr_base = accel->bar->virt_addr; + orphan_bundle->csr_base = csr_base; + orphan_bundle->bank = bank; + + orphan_bundle->tx_mask = 0; + orphan_bundle->rx_mask = 0; + tx_mask = accel_dev->hw_device->tx_rings_mask; + asym_mask = accel_dev->hw_device->asym_rings_mask; + + /* Get ring mask for this process. */ + bundle = &accel->bundle[bank]; + orphan_bundle->bundle = bundle; + mutex_lock(&bundle->list_lock); + list_for_each(entry, &bundle->list) + { + instance_rings = + list_entry(entry, struct adf_uio_instance_rings, list); + if (instance_rings->user_pid == curproc->p_pid) { + ring_mask = instance_rings->ring_mask; + break; + } + } + mutex_unlock(&bundle->list_lock); + + for (i = 0; i < num_rings_per_bank; i++) { + base = csr_ops->read_csr_ring_base(csr_base, bank, i); + + if (!base) + continue; + if (!(ring_mask & 1 << i)) + continue; /* Not reserved for this process. */ + + if (test_bit(i, &tx_mask)) + __set_bit(i, &orphan_bundle->tx_mask); + else + __set_bit(i, &orphan_bundle->rx_mask); + + if (test_bit(i, &asym_mask)) + __set_bit(i, &orphan_bundle->asym_mask); + } + + if (orphan_bundle->tx_mask || orphan_bundle->rx_mask) + check_orphan_ring(accel_dev, orphan_bundle, hw_data); + + *orphan_bundle_out = orphan_bundle; + return ret; +} + +static void +put_orphan_bundle(struct bundle_orphan_ring *bundle) +{ + if (!bundle) + return; + + free(bundle, M_QAT); +} + +/* cleanup all ring */ +static void +cleanup_all_ring(struct adf_uio_control_accel *accel, + struct bundle_orphan_ring *orphan) +{ + int i; + struct resource *csr_base = orphan->csr_base; + unsigned long mask = orphan->rx_mask | orphan->tx_mask; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + int bank = orphan->bank; + + mutex_lock(&orphan->bundle->lock); + orphan->bundle->rings_enabled &= ~mask; + adf_update_uio_ring_arb(orphan->bundle); + mutex_unlock(&orphan->bundle->lock); + + for (i = 0; i < num_rings_per_bank; i++) { + if (!test_bit(i, &mask)) + continue; + + csr_ops->write_csr_ring_config(csr_base, bank, i, 0); + csr_ops->write_csr_ring_base(csr_base, bank, i, 0); + } +} + +/* + * Return true, if number of messages in tx ring is equal to number + * of messages in corresponding rx ring, else false. + */ +static bool +is_all_resp_recvd(struct adf_hw_csr_ops *csr_ops, + struct bundle_orphan_ring *bundle, + const u8 num_rings_per_bank) +{ + u32 rx_tail = 0, tx_head = 0, rx_ring_msg_offset = 0, + tx_ring_msg_offset = 0, tx_rx_offset = num_rings_per_bank / 2, + idx = 0, retry = 0, delay = ADF_RING_EMPTY_RETRY_DELAY; + + do { + for_each_set_bit(idx, &bundle->tx_mask, tx_rx_offset) + { + rx_tail = + csr_ops->read_csr_ring_tail(bundle->csr_base, + 0, + (idx + tx_rx_offset)); + tx_head = csr_ops->read_csr_ring_head(bundle->csr_base, + 0, + idx); + + /* + * Normalize messages in tx rings to match rx ring + * message size, i.e., size of response message(32). + * Asym messages are 64 bytes each, so right shift + * by 1 to normalize to 32. Sym and compression + * messages are 128 bytes each, so right shift by 2 + * to normalize to 32. + */ + if (bundle->asym_mask & (1 << idx)) + tx_ring_msg_offset = (tx_head >> 1); + else + tx_ring_msg_offset = (tx_head >> 2); + + rx_ring_msg_offset = rx_tail; + + if (tx_ring_msg_offset != rx_ring_msg_offset) + break; + } + if (idx == tx_rx_offset) + /* All Tx and Rx ring message counts match */ + return true; + + DELAY(delay); + delay *= 2; + } while (++retry < ADF_RING_EMPTY_MAX_RETRY); + + return false; +} + +static int +bundle_need_cleanup(int bank, struct adf_uio_control_accel *accel) +{ + struct resource *csr_base = accel->bar->virt_addr; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + int i; + + if (!csr_base) + return 0; + + for (i = 0; i < num_rings_per_bank; i++) { + if (csr_ops->read_csr_ring_base(csr_base, bank, i)) + return 1; + } + + return 0; +} + +static void +cleanup_orphan_ring(struct bundle_orphan_ring *orphan, + struct adf_uio_control_accel *accel) +{ + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 number_rings_per_bank = hw_data->num_rings_per_bank; + + /* disable the interrupt */ + csr_ops->write_csr_int_col_en(orphan->csr_base, orphan->bank, 0); + + /* + * wait firmware finish the in-process ring + * 1. disable all tx rings + * 2. check if all responses are received + * 3. reset all rings + */ + adf_disable_ring_arb(accel_dev, orphan->csr_base, 0, orphan->tx_mask); + + if (!is_all_resp_recvd(csr_ops, orphan, number_rings_per_bank)) { + device_printf(GET_DEV(accel_dev), + "Failed to clean up orphan rings"); + return; + } + + /* + * When the execution reaches here, it is assumed that + * there is no inflight request in the rings and that + * there is no in-process ring. + */ + + cleanup_all_ring(accel, orphan); +} + +void +adf_uio_do_cleanup_orphan(int bank, struct adf_uio_control_accel *accel) +{ + int ret, pid_found; + struct adf_uio_instance_rings *instance_rings, *tmp; + struct adf_uio_control_bundle *bundle; + /* orphan is local pointer allocated and deallocated in this function */ + struct bundle_orphan_ring *orphan = NULL; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + if (!bundle_need_cleanup(bank, accel)) + goto release; + + ret = get_orphan_bundle(bank, accel, &orphan); + if (ret != 0) + return; + + /* + * If driver supports ring pair reset, no matter process + * exits normally or abnormally, just do ring pair reset. + * ring pair reset will reset all ring pair registers to + * default value. Driver only needs to reset ring mask + */ + if (hw_data->ring_pair_reset) { + hw_data->ring_pair_reset( + accel_dev, orphan->bundle->hardware_bundle_number); + mutex_lock(&orphan->bundle->lock); + /* + * If processes exit normally, rx_mask, tx_mask + * and rings_enabled are all 0, below expression + * have no impact on rings_enabled. + * If processes exit abnormally, rings_enabled + * will be set as 0 by below expression. + */ + orphan->bundle->rings_enabled &= + ~(orphan->rx_mask | orphan->tx_mask); + mutex_unlock(&orphan->bundle->lock); + goto out; + } + + if (!orphan->tx_mask && !orphan->rx_mask) + goto out; + + device_printf(GET_DEV(accel_dev), + "Process %d %s exit with orphan rings %lx:%lx\n", + curproc->p_pid, + curproc->p_comm, + orphan->tx_mask, + orphan->rx_mask); + + if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status)) { + cleanup_orphan_ring(orphan, accel); + } +out: + put_orphan_bundle(orphan); + +release: + + bundle = &accel->bundle[bank]; + /* + * If the user process died without releasing the rings + * then force a release here. + */ + mutex_lock(&bundle->list_lock); + pid_found = 0; + list_for_each_entry_safe(instance_rings, tmp, &bundle->list, list) + { + if (instance_rings->user_pid == curproc->p_pid) { + pid_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (pid_found) { + mutex_lock(&bundle->lock); + bundle->rings_used &= ~instance_rings->ring_mask; + mutex_unlock(&bundle->lock); + } +} diff --git a/sys/dev/qat/qat_common/adf_gen2_hw_data.c b/sys/dev/qat/qat_common/adf_gen2_hw_data.c index d3babf8800ba..c440102e32a2 100644 --- a/sys/dev/qat/qat_common/adf_gen2_hw_data.c +++ b/sys/dev/qat/qat_common/adf_gen2_hw_data.c @@ -55,6 +55,12 @@ write_csr_ring_config(struct resource *csr_base_addr, WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value); } +static dma_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE(csr_base_addr, bank, ring); +} + static void write_csr_ring_base(struct resource *csr_base_addr, u32 bank, @@ -106,6 +112,12 @@ write_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank, u32 value) WRITE_CSR_RING_SRV_ARB_EN(csr_base_addr, bank, value); } +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + void adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) { @@ -113,6 +125,9 @@ adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_info->arb_enable_mask = 0xFF; + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE; + csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; csr_ops->read_csr_ring_head = read_csr_ring_head; csr_ops->write_csr_ring_head = write_csr_ring_head; @@ -120,6 +135,7 @@ adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_ops->write_csr_ring_tail = write_csr_ring_tail; csr_ops->read_csr_e_stat = read_csr_e_stat; csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; csr_ops->write_csr_ring_base = write_csr_ring_base; csr_ops->write_csr_int_flag = write_csr_int_flag; csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; @@ -128,5 +144,5 @@ adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; } -EXPORT_SYMBOL_GPL(adf_gen2_init_hw_csr_info); diff --git a/sys/dev/qat/qat_common/adf_gen4_hw_data.c b/sys/dev/qat/qat_common/adf_gen4_hw_data.c index aae54898afb1..9a2668412819 100644 --- a/sys/dev/qat/qat_common/adf_gen4_hw_data.c +++ b/sys/dev/qat/qat_common/adf_gen4_hw_data.c @@ -2,8 +2,12 @@ /* Copyright(c) 2021 Intel Corporation */ /* $FreeBSD$ */ #include "adf_accel_devices.h" +#include "adf_common_drv.h" #include "adf_gen4_hw_data.h" +#define ADF_RPRESET_TIMEOUT_MS 5000 +#define ADF_RPRESET_POLLING_INTERVAL 20 + static u64 build_csr_ring_base_addr(bus_addr_t addr, u32 size) { @@ -55,6 +59,12 @@ write_csr_ring_config(struct resource *csr_base_addr, WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value); } +static bus_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE(csr_base_addr, bank, ring); +} + static void write_csr_ring_base(struct resource *csr_base_addr, u32 bank, @@ -106,6 +116,12 @@ write_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank, u32 value) WRITE_CSR_RING_SRV_ARB_EN(csr_base_addr, bank, value); } +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + void adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info) { @@ -113,6 +129,9 @@ adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_info->arb_enable_mask = 0x1; + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE; + csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; csr_ops->read_csr_ring_head = read_csr_ring_head; csr_ops->write_csr_ring_head = write_csr_ring_head; @@ -120,6 +139,7 @@ adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_ops->write_csr_ring_tail = write_csr_ring_tail; csr_ops->read_csr_e_stat = read_csr_e_stat; csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; csr_ops->write_csr_ring_base = write_csr_ring_base; csr_ops->write_csr_int_flag = write_csr_int_flag; csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; @@ -128,8 +148,64 @@ adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info) csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; +} + +static int +reset_ring_pair(struct resource *csr, u32 bank_number) +{ + int reset_timeout = ADF_RPRESET_TIMEOUT_MS; + const int timeout_step = ADF_RPRESET_POLLING_INTERVAL; + u32 val; + + /* Write rpresetctl register bit#0 as 1 + * As rpresetctl registers have no RW bits, no need to preserve + * values for other bits, just write bit#0 + * NOTE: bit#12-bit#31 are WO, the write operation only takes + * effect when bit#1 is written 1 for pasid level reset + */ + ADF_CSR_WR(csr, + ADF_WQM_CSR_RPRESETCTL(bank_number), + BIT(ADF_WQM_CSR_RPRESETCTL_SHIFT)); + + /* Read rpresetsts register to wait for rp reset complete */ + while (reset_timeout > 0) { + val = ADF_CSR_RD(csr, ADF_WQM_CSR_RPRESETSTS(bank_number)); + if (val & ADF_WQM_CSR_RPRESETSTS_MASK) + break; + pause_ms("adfstop", timeout_step); + reset_timeout -= timeout_step; + } + if (reset_timeout <= 0) + return EFAULT; + + /* When rp reset is done, clear rpresetsts bit0 */ + ADF_CSR_WR(csr, + ADF_WQM_CSR_RPRESETSTS(bank_number), + BIT(ADF_WQM_CSR_RPRESETSTS_SHIFT)); + return 0; +} + +int +adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u32 etr_bar_id = hw_data->get_etr_bar_id(hw_data); + struct resource *csr; + int ret; + + if (bank_number >= hw_data->num_banks) + return -EINVAL; + + csr = (&GET_BARS(accel_dev)[etr_bar_id])->virt_addr; + + ret = reset_ring_pair(csr, bank_number); + if (ret) + device_printf(GET_DEV(accel_dev), + "ring pair reset failure (timeout)\n"); + + return ret; } -EXPORT_SYMBOL_GPL(adf_gen4_init_hw_csr_info); static inline void adf_gen4_unpack_ssm_wdtimer(u64 value, u32 *upper, u32 *lower) @@ -173,4 +249,9 @@ adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev) return 0; } -EXPORT_SYMBOL_GPL(adf_gen4_set_ssm_wdtimer); + +int +adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev) +{ + return 0; +} diff --git a/sys/dev/qat/qat_common/adf_gen4_pfvf.c b/sys/dev/qat/qat_common/adf_gen4_pfvf.c new file mode 100644 index 000000000000..0cbf19dc07a8 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_gen4_pfvf.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_gen4_pfvf.h" +#include "adf_pfvf_utils.h" +#include "adf_pfvf_vf_proto.h" + +#define ADF_4XXX_PF2VM_OFFSET(i) (0x40B010 + ((i)*0x20)) +#define ADF_4XXX_VM2PF_OFFSET(i) (0x40B014 + ((i)*0x20)) + +/* VF2PF interrupt source registers */ +#define ADF_4XXX_VM2PF_SOU 0x41A180 +#define ADF_4XXX_VM2PF_MSK 0x41A1C0 +#define ADF_GEN4_VF_MSK 0xFFFF + +#define ADF_PFVF_GEN4_MSGTYPE_SHIFT 2 +#define ADF_PFVF_GEN4_MSGTYPE_MASK 0x3F +#define ADF_PFVF_GEN4_MSGDATA_SHIFT 8 +#define ADF_PFVF_GEN4_MSGDATA_MASK 0xFFFFFF + +#define ADF_4XXXIOV_PF2VM_OFFSET 0x100C +#define ADF_4XXXIOV_VM2PF_OFFSET 0x1008 +static const struct pfvf_csr_format csr_gen4_fmt = { + { ADF_PFVF_GEN4_MSGTYPE_SHIFT, ADF_PFVF_GEN4_MSGTYPE_MASK }, + { ADF_PFVF_GEN4_MSGDATA_SHIFT, ADF_PFVF_GEN4_MSGDATA_MASK }, +}; + +static u32 +adf_gen4_vf_get_pfvf_offset(u32 i) +{ + return ADF_4XXXIOV_PF2VM_OFFSET; +} + +static u32 +adf_gen4_vf_get_vfpf_offset(u32 i) +{ + return ADF_4XXXIOV_VM2PF_OFFSET; +} + +static int +adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + u32 pfvf_offset, + struct mutex *csr_lock) +{ + struct resource *pmisc_addr = adf_get_pmisc_base(accel_dev); + u32 csr_val; + int ret; + csr_val = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen4_fmt); + if (unlikely(!csr_val)) + return -EINVAL; + + mutex_lock(csr_lock); + + ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val | ADF_PFVF_INT); + + /* Wait for confirmation from remote that it received the message */ + ret = read_poll_timeout(ADF_CSR_RD, + csr_val, + !(csr_val & ADF_PFVF_INT), + ADF_PFVF_MSG_ACK_DELAY_US, + ADF_PFVF_MSG_ACK_MAX_DELAY_US, + true, + pmisc_addr, + pfvf_offset); + if (ret < 0) + device_printf(GET_DEV(accel_dev), + "ACK not received from remote\n"); + + mutex_unlock(csr_lock); + return ret; +} + +static int +adf_gen4_vf2pf_send(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + u32 pfvf_offset, + struct mutex *csr_lock) +{ + return adf_gen4_pfvf_send(accel_dev, msg, pfvf_offset, csr_lock); +} + +static struct pfvf_message +adf_gen4_pfvf_recv(struct adf_accel_dev *accel_dev, + u32 pfvf_offset, + u8 compat_ver) +{ + struct resource *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct pfvf_message msg = { 0 }; + u32 csr_val; + + /* Read message from the CSR */ + csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset); + if (!(csr_val & ADF_PFVF_INT)) { + device_printf(GET_DEV(accel_dev), + "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", + csr_val); + return msg; + } + + /* We can now acknowledge the message reception by clearing the + * interrupt bit + */ + ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val & ~ADF_PFVF_INT); + + /* Return the pfvf_message format */ + return adf_pfvf_message_of(accel_dev, csr_val, &csr_gen4_fmt); +} + +static struct pfvf_message +adf_gen4_pf2vf_recv(struct adf_accel_dev *accel_dev, + u32 pfvf_offset, + u8 compat_ver) +{ + return adf_gen4_pfvf_recv(accel_dev, pfvf_offset, compat_ver); +} + +void +adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_enable_vf2pf_comms; + pfvf_ops->get_pf2vf_offset = adf_gen4_vf_get_pfvf_offset; + pfvf_ops->get_vf2pf_offset = adf_gen4_vf_get_vfpf_offset; + pfvf_ops->send_msg = adf_gen4_vf2pf_send; + pfvf_ops->recv_msg = adf_gen4_pf2vf_recv; +} diff --git a/sys/dev/qat/qat_common/adf_gen4_timer.c b/sys/dev/qat/qat_common/adf_gen4_timer.c new file mode 100644 index 000000000000..cb929586dab8 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_gen4_timer.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "adf_accel_devices.h" +#include "adf_heartbeat.h" +#include "adf_common_drv.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_gen4_timer.h" + +#include "adf_dev_err.h" + +#define ADF_GEN4_INT_TIMER_VALUE_IN_MS 200 +/* Interval within timer interrupt. Value in miliseconds. */ + +#define ADF_GEN4_MAX_INT_TIMER_VALUE_IN_MS 0xFFFFFFFF +/* MAX Interval within timer interrupt. Value in miliseconds. */ + +static u64 +adf_get_next_timeout(u32 timeout_val) +{ + u64 timeout = msecs_to_jiffies(timeout_val); + + return rounddown(jiffies + timeout, timeout); +} + +static void +adf_hb_irq_bh_handler(struct work_struct *work) +{ + struct icp_qat_fw_init_admin_req req = { 0 }; + struct icp_qat_fw_init_admin_resp resp = { 0 }; + struct adf_hb_timer_data *hb_timer_data = + container_of(work, struct adf_hb_timer_data, hb_int_timer_work); + struct adf_accel_dev *accel_dev = hb_timer_data->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u32 ae_mask = hw_data->ae_mask; + + if (!accel_dev->int_timer || !accel_dev->int_timer->enabled) + goto end; + + /* Update heartbeat count via init/admin cmd */ + if (!accel_dev->admin) { + device_printf(GET_DEV(accel_dev), + "adf_admin is not available\n"); + goto end; + } + + req.cmd_id = ICP_QAT_FW_HEARTBEAT_SYNC; + req.heartbeat_ticks = accel_dev->int_timer->int_cnt; + + if (adf_send_admin(accel_dev, &req, &resp, ae_mask)) + device_printf(GET_DEV(accel_dev), + "Failed to update qat's HB count\n"); + +end: + kfree(hb_timer_data); +} + +static void +timer_handler(struct timer_list *tl) +{ + struct adf_int_timer *int_timer = from_timer(int_timer, tl, timer); + struct adf_accel_dev *accel_dev = int_timer->accel_dev; + struct adf_hb_timer_data *hb_timer_data = NULL; + u64 timeout_val = adf_get_next_timeout(int_timer->timeout_val); + /* Update TL TBD */ + + /* Schedule a heartbeat work queue to update HB */ + hb_timer_data = kzalloc(sizeof(*hb_timer_data), GFP_ATOMIC); + if (hb_timer_data) { + hb_timer_data->accel_dev = accel_dev; + + INIT_WORK(&hb_timer_data->hb_int_timer_work, + adf_hb_irq_bh_handler); + queue_work(int_timer->timer_irq_wq, + &hb_timer_data->hb_int_timer_work); + } else { + device_printf(GET_DEV(accel_dev), + "Failed to alloc heartbeat timer data\n"); + } + int_timer->int_cnt++; + mod_timer(tl, timeout_val); +} + +int +adf_int_timer_init(struct adf_accel_dev *accel_dev) +{ + u64 timeout_val = adf_get_next_timeout(ADF_GEN4_INT_TIMER_VALUE_IN_MS); + struct adf_int_timer *int_timer = NULL; + char wqname[32] = { 0 }; + + if (!accel_dev) + return 0; + + int_timer = kzalloc(sizeof(*int_timer), GFP_KERNEL); + if (!int_timer) + return -ENOMEM; + + sprintf(wqname, "qat_timer_wq_%d", accel_dev->accel_id); + + int_timer->timer_irq_wq = alloc_workqueue(wqname, WQ_MEM_RECLAIM, 1); + + if (!int_timer->timer_irq_wq) { + kfree(int_timer); + return -ENOMEM; + } + + int_timer->accel_dev = accel_dev; + int_timer->timeout_val = ADF_GEN4_INT_TIMER_VALUE_IN_MS; + int_timer->int_cnt = 0; + int_timer->enabled = true; + accel_dev->int_timer = int_timer; + + timer_setup(&int_timer->timer, timer_handler, 0); + mod_timer(&int_timer->timer, timeout_val); + + return 0; +} + +void +adf_int_timer_exit(struct adf_accel_dev *accel_dev) +{ + if (accel_dev && accel_dev->int_timer) { + del_timer_sync(&accel_dev->int_timer->timer); + accel_dev->int_timer->enabled = false; + + if (accel_dev->int_timer->timer_irq_wq) { + flush_workqueue(accel_dev->int_timer->timer_irq_wq); + destroy_workqueue(accel_dev->int_timer->timer_irq_wq); + } + + kfree(accel_dev->int_timer); + accel_dev->int_timer = NULL; + } +} diff --git a/sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c b/sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c new file mode 100644 index 000000000000..78a6fea7a827 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "adf_accel_devices.h" +#include "adf_gen4vf_hw_csr_data.h" + +static u64 +build_csr_ring_base_addr(dma_addr_t addr, u32 size) +{ + return BUILD_RING_BASE_ADDR_GEN4(addr, size); +} + +static u32 +read_csr_ring_head(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring); +} + +static void +write_csr_ring_head(struct resource *csr_base_addr, + u32 bank, + u32 ring, + u32 value) +{ + WRITE_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring, value); +} + +static u32 +read_csr_ring_tail(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring); +} + +static void +write_csr_ring_tail(struct resource *csr_base_addr, + u32 bank, + u32 ring, + u32 value) +{ + WRITE_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring, value); +} + +static u32 +read_csr_e_stat(struct resource *csr_base_addr, u32 bank) +{ + return READ_CSR_E_STAT_GEN4VF(csr_base_addr, bank); +} + +static void +write_csr_ring_config(struct resource *csr_base_addr, + u32 bank, + u32 ring, + u32 value) +{ + WRITE_CSR_RING_CONFIG_GEN4VF(csr_base_addr, bank, ring, value); +} + +static dma_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring); +} + +static void +write_csr_ring_base(struct resource *csr_base_addr, + u32 bank, + u32 ring, + dma_addr_t addr) +{ + WRITE_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring, addr); +} + +static void +write_csr_int_flag(struct resource *csr_base_addr, u32 bank, u32 value) +{ + WRITE_CSR_INT_FLAG_GEN4VF(csr_base_addr, bank, value); +} + +static void +write_csr_int_srcsel(struct resource *csr_base_addr, u32 bank) +{ + WRITE_CSR_INT_SRCSEL_GEN4VF(csr_base_addr, bank); +} + +static void +write_csr_int_col_en(struct resource *csr_base_addr, u32 bank, u32 value) +{ + WRITE_CSR_INT_COL_EN_GEN4VF(csr_base_addr, bank, value); +} + +static void +write_csr_int_col_ctl(struct resource *csr_base_addr, u32 bank, u32 value) +{ + WRITE_CSR_INT_COL_CTL_GEN4VF(csr_base_addr, bank, value); +} + +static void +write_csr_int_flag_and_col(struct resource *csr_base_addr, u32 bank, u32 value) +{ + WRITE_CSR_INT_FLAG_AND_COL_GEN4VF(csr_base_addr, bank, value); +} + +static u32 +read_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank) +{ + return READ_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank); +} + +static void +write_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank, u32 value) +{ + WRITE_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank, value); +} + +static u32 +get_src_sel_mask(void) +{ + return ADF_BANK_INT_SRC_SEL_MASK_GEN4; +} + +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + +static u32 +get_bank_irq_mask(u32 irq_mask) +{ + return 0x1; +} + +void +gen4vf_init_hw_csr_info(struct adf_hw_csr_info *csr_info) +{ + struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops; + + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET_GEN4VF; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE_GEN4; + csr_info->bank_int_flag_clear_mask = ADF_BANK_INT_FLAG_CLEAR_MASK_GEN4; + csr_info->num_rings_per_int_srcsel = ADF_RINGS_PER_INT_SRCSEL_GEN4; + csr_info->arb_enable_mask = 0x1; + csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; + csr_ops->read_csr_ring_head = read_csr_ring_head; + csr_ops->write_csr_ring_head = write_csr_ring_head; + csr_ops->read_csr_ring_tail = read_csr_ring_tail; + csr_ops->write_csr_ring_tail = write_csr_ring_tail; + csr_ops->read_csr_e_stat = read_csr_e_stat; + csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; + csr_ops->write_csr_ring_base = write_csr_ring_base; + csr_ops->write_csr_int_flag = write_csr_int_flag; + csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; + csr_ops->write_csr_int_col_en = write_csr_int_col_en; + csr_ops->write_csr_int_col_ctl = write_csr_int_col_ctl; + csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; + csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; + csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_src_sel_mask = get_src_sel_mask; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; + csr_ops->get_bank_irq_mask = get_bank_irq_mask; +} diff --git a/sys/dev/qat/qat_common/adf_hw_arbiter.c b/sys/dev/qat/qat_common/adf_hw_arbiter.c index 827d612e2c22..5dfa8c6a7bf5 100644 --- a/sys/dev/qat/qat_common/adf_hw_arbiter.c +++ b/sys/dev/qat/qat_common/adf_hw_arbiter.c @@ -114,6 +114,25 @@ adf_update_ring_arb(struct adf_etr_ring_data *ring) arben); } +void +adf_update_uio_ring_arb(struct adf_uio_control_bundle *bundle) +{ + int shift; + u32 arben, arben_tx, arben_rx, arb_mask; + struct adf_accel_dev *accel_dev = bundle->uio_priv.accel->accel_dev; + struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info; + struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops; + + arb_mask = csr_info->arb_enable_mask; + shift = hweight32(arb_mask); + + arben_tx = bundle->rings_enabled & arb_mask; + arben_rx = (bundle->rings_enabled >> shift) & arb_mask; + arben = arben_tx & arben_rx; + csr_ops->write_csr_ring_srv_arb_en(bundle->csr_addr, + bundle->hardware_bundle_number, + arben); +} void adf_enable_ring_arb(struct adf_accel_dev *accel_dev, void *csr_addr, @@ -121,16 +140,15 @@ adf_enable_ring_arb(struct adf_accel_dev *accel_dev, unsigned int mask) { struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); - struct resource *csr = csr_addr; u32 arbenable; - if (!csr) + if (!csr_addr) return; mutex_lock(&csr_arb_lock); - arbenable = csr_ops->read_csr_ring_srv_arb_en(csr, bank_nr); + arbenable = csr_ops->read_csr_ring_srv_arb_en(csr_addr, bank_nr); arbenable |= mask & 0xFF; - csr_ops->write_csr_ring_srv_arb_en(csr, bank_nr, arbenable); + csr_ops->write_csr_ring_srv_arb_en(csr_addr, bank_nr, arbenable); mutex_unlock(&csr_arb_lock); } diff --git a/sys/dev/qat/qat_common/adf_init.c b/sys/dev/qat/qat_common/adf_init.c index 0fb8618b1f32..3f9f1382d11f 100644 --- a/sys/dev/qat/qat_common/adf_init.c +++ b/sys/dev/qat/qat_common/adf_init.c @@ -10,6 +10,7 @@ #include "icp_qat_fw_init_admin.h" #include "adf_cfg_strings.h" #include "adf_dev_err.h" +#include "adf_uio.h" #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" #include @@ -77,7 +78,6 @@ adf_cfg_add_device_params(struct adf_accel_dev *accel_dev) char mmp_version[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; struct adf_hw_device_data *hw_data = NULL; unsigned long val; - if (!accel_dev) return -EINVAL; @@ -349,18 +349,9 @@ adf_dev_init(struct adf_accel_dev *accel_dev) hw_data->enable_error_correction(accel_dev); - if (hw_data->enable_vf2pf_comms && - hw_data->enable_vf2pf_comms(accel_dev)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed to enable vf2pf comms\n"); - return EFAULT; - } - - if (adf_pf_vf_capabilities_init(accel_dev)) - return EFAULT; - - if (adf_pf_vf_ring_to_svc_init(accel_dev)) - return EFAULT; + ret = hw_data->csr_info.pfvf_ops.enable_comms(accel_dev); + if (ret) + return ret; if (adf_cfg_add_device_params(accel_dev)) return EFAULT; @@ -462,6 +453,12 @@ adf_dev_start(struct adf_accel_dev *accel_dev) return EFAULT; } + if (hw_data->int_timer_init && hw_data->int_timer_init(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Failed to init heartbeat interrupt timer\n"); + return -EFAULT; + } + list_for_each(list_itr, &service_table) { service = list_entry(list_itr, struct service_hndl, list); @@ -474,6 +471,18 @@ adf_dev_start(struct adf_accel_dev *accel_dev) set_bit(accel_dev->accel_id, service->start_status); } + if (accel_dev->is_vf || !accel_dev->u1.pf.vf_info) { + /*Register UIO devices */ + if (adf_uio_register(accel_dev)) { + adf_uio_remove(accel_dev); + device_printf(GET_DEV(accel_dev), + "Failed to register UIO devices\n"); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ENODEV; + } + } + if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status) && adf_cfg_add_ext_params(accel_dev)) return EFAULT; @@ -521,6 +530,9 @@ adf_dev_stop(struct adf_accel_dev *accel_dev) clear_bit(ADF_STATUS_STARTING, &accel_dev->status); clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + if (accel_dev->hw_device->int_timer_exit) + accel_dev->hw_device->int_timer_exit(accel_dev); + list_for_each(list_itr, &service_table) { service = list_entry(list_itr, struct service_hndl, list); @@ -529,6 +541,11 @@ adf_dev_stop(struct adf_accel_dev *accel_dev) clear_bit(accel_dev->accel_id, service->start_status); } + if (accel_dev->is_vf || !accel_dev->u1.pf.vf_info) { + /* Remove UIO Devices */ + adf_uio_remove(accel_dev); + } + if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) { if (adf_ae_stop(accel_dev)) device_printf(GET_DEV(accel_dev), @@ -596,9 +613,6 @@ adf_dev_shutdown(struct adf_accel_dev *accel_dev) hw_data->disable_iov(accel_dev); - if (hw_data->disable_vf2pf_comms) - hw_data->disable_vf2pf_comms(accel_dev); - if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) { hw_data->free_irq(accel_dev); clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status); diff --git a/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c b/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c deleted file mode 100644 index f4b4a3faf305..000000000000 --- a/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c +++ /dev/null @@ -1,147 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" -#include "adf_cfg.h" - -#define ADF_VF2PF_CAPABILITIES_V1_VERSION 1 -#define ADF_VF2PF_CAPABILITIES_V1_LENGTH 4 -#define ADF_VF2PF_CAPABILITIES_V2_VERSION 2 -#define ADF_VF2PF_CAPABILITIES_CAP_OFFSET 4 -#define ADF_VF2PF_CAPABILITIES_V2_LENGTH 8 -#define ADF_VF2PF_CAPABILITIES_V3_VERSION 3 -#define ADF_VF2PF_CAPABILITIES_FREQ_OFFSET 8 -#define ADF_VF2PF_CAPABILITIES_V3_LENGTH 12 - -static int -adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num) -{ - static u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 }; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - u32 ext_dc_caps = hw_data->extended_dc_capabilities; - u32 capabilities = hw_data->accel_capabilities_mask; - u32 frequency = hw_data->clock_frequency; - u16 byte = 0; - u16 index = 0; - - for (byte = 0; byte < sizeof(ext_dc_caps); byte++) { - data[byte] = (ext_dc_caps >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - for (byte = 0, index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET; - byte < sizeof(capabilities); - byte++, index++) { - data[index] = (capabilities >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - if (frequency) { - for (byte = 0, index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET; - byte < sizeof(frequency); - byte++, index++) { - data[index] = - (frequency >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - *length = ADF_VF2PF_CAPABILITIES_V3_LENGTH; - *block_version = ADF_VF2PF_CAPABILITIES_V3_VERSION; - } else { - *length = ADF_VF2PF_CAPABILITIES_V2_LENGTH; - *block_version = ADF_VF2PF_CAPABILITIES_V2_VERSION; - } - - *buffer = data; - return 0; -} - -int -adf_pf_vf_capabilities_init(struct adf_accel_dev *accel_dev) -{ - u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 }; - u8 len = ADF_VF2PF_CAPABILITIES_V3_LENGTH; - u8 version = ADF_VF2PF_CAPABILITIES_V2_VERSION; - u32 ex_dc_cap = 0; - u32 capabilities = 0; - u32 frequency = 0; - u16 byte = 0; - u16 index = 0; - - if (!accel_dev->is_vf) { - /* on the pf */ - if (!adf_iov_is_block_provider_registered( - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY)) - adf_iov_block_provider_register( - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY, - adf_pf_capabilities_msg_provider); - } else if (accel_dev->u1.vf.pf_version >= - ADF_PFVF_COMPATIBILITY_CAPABILITIES) { - /* on the vf */ - if (adf_iov_block_get(accel_dev, - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY, - &version, - data, - &len)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed adf_iov_block_get\n"); - return EFAULT; - } - - if (len < ADF_VF2PF_CAPABILITIES_V1_LENGTH) { - device_printf( - GET_DEV(accel_dev), - "Capabilities message truncated to %d bytes\n", - len); - return EFAULT; - } - - for (byte = 0; byte < sizeof(ex_dc_cap); byte++) { - ex_dc_cap |= data[byte] << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->extended_dc_capabilities = ex_dc_cap; - - /* Get capabilities if provided by PF */ - if (len >= ADF_VF2PF_CAPABILITIES_V2_LENGTH) { - for (byte = 0, - index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET; - byte < sizeof(capabilities); - byte++, index++) { - capabilities |= data[index] - << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->accel_capabilities_mask = - capabilities; - } else { - device_printf(GET_DEV(accel_dev), - "PF did not communicate capabilities\n"); - } - - /* Get frequency if provided by the PF */ - if (len >= ADF_VF2PF_CAPABILITIES_V3_LENGTH) { - for (byte = 0, - index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET; - byte < sizeof(frequency); - byte++, index++) { - frequency |= data[index] - << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->clock_frequency = frequency; - } else { - device_printf(GET_DEV(accel_dev), - "PF did not communicate frequency\n"); - } - - } else { - /* The PF is too old to support the extended capabilities */ - accel_dev->hw_device->extended_dc_capabilities = 0; - } - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_pf2vf_msg.c b/sys/dev/qat/qat_common/adf_pf2vf_msg.c deleted file mode 100644 index 60b1102f4700..000000000000 --- a/sys/dev/qat/qat_common/adf_pf2vf_msg.c +++ /dev/null @@ -1,896 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" - -adf_iov_block_provider - pf2vf_message_providers[ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE + 1]; -unsigned char pfvf_crc8_table[] = - { 0x00, 0x97, 0xB9, 0x2E, 0xE5, 0x72, 0x5C, 0xCB, 0x5D, 0xCA, 0xE4, 0x73, - 0xB8, 0x2F, 0x01, 0x96, 0xBA, 0x2D, 0x03, 0x94, 0x5F, 0xC8, 0xE6, 0x71, - 0xE7, 0x70, 0x5E, 0xC9, 0x02, 0x95, 0xBB, 0x2C, 0xE3, 0x74, 0x5A, 0xCD, - 0x06, 0x91, 0xBF, 0x28, 0xBE, 0x29, 0x07, 0x90, 0x5B, 0xCC, 0xE2, 0x75, - 0x59, 0xCE, 0xE0, 0x77, 0xBC, 0x2B, 0x05, 0x92, 0x04, 0x93, 0xBD, 0x2A, - 0xE1, 0x76, 0x58, 0xCF, 0x51, 0xC6, 0xE8, 0x7F, 0xB4, 0x23, 0x0D, 0x9A, - 0x0C, 0x9B, 0xB5, 0x22, 0xE9, 0x7E, 0x50, 0xC7, 0xEB, 0x7C, 0x52, 0xC5, - 0x0E, 0x99, 0xB7, 0x20, 0xB6, 0x21, 0x0F, 0x98, 0x53, 0xC4, 0xEA, 0x7D, - 0xB2, 0x25, 0x0B, 0x9C, 0x57, 0xC0, 0xEE, 0x79, 0xEF, 0x78, 0x56, 0xC1, - 0x0A, 0x9D, 0xB3, 0x24, 0x08, 0x9F, 0xB1, 0x26, 0xED, 0x7A, 0x54, 0xC3, - 0x55, 0xC2, 0xEC, 0x7B, 0xB0, 0x27, 0x09, 0x9E, 0xA2, 0x35, 0x1B, 0x8C, - 0x47, 0xD0, 0xFE, 0x69, 0xFF, 0x68, 0x46, 0xD1, 0x1A, 0x8D, 0xA3, 0x34, - 0x18, 0x8F, 0xA1, 0x36, 0xFD, 0x6A, 0x44, 0xD3, 0x45, 0xD2, 0xFC, 0x6B, - 0xA0, 0x37, 0x19, 0x8E, 0x41, 0xD6, 0xF8, 0x6F, 0xA4, 0x33, 0x1D, 0x8A, - 0x1C, 0x8B, 0xA5, 0x32, 0xF9, 0x6E, 0x40, 0xD7, 0xFB, 0x6C, 0x42, 0xD5, - 0x1E, 0x89, 0xA7, 0x30, 0xA6, 0x31, 0x1F, 0x88, 0x43, 0xD4, 0xFA, 0x6D, - 0xF3, 0x64, 0x4A, 0xDD, 0x16, 0x81, 0xAF, 0x38, 0xAE, 0x39, 0x17, 0x80, - 0x4B, 0xDC, 0xF2, 0x65, 0x49, 0xDE, 0xF0, 0x67, 0xAC, 0x3B, 0x15, 0x82, - 0x14, 0x83, 0xAD, 0x3A, 0xF1, 0x66, 0x48, 0xDF, 0x10, 0x87, 0xA9, 0x3E, - 0xF5, 0x62, 0x4C, 0xDB, 0x4D, 0xDA, 0xF4, 0x63, 0xA8, 0x3F, 0x11, 0x86, - 0xAA, 0x3D, 0x13, 0x84, 0x4F, 0xD8, 0xF6, 0x61, 0xF7, 0x60, 0x4E, 0xD9, - 0x12, 0x85, 0xAB, 0x3C }; - -void -adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_vintmsk_offset(0), 0x0); -} - -void -adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_vintmsk_offset(0), 0x2); -} - -static int -__adf_iov_putmsg(struct adf_accel_dev *accel_dev, - u32 msg, - u8 vf_nr, - bool is_notification) -{ - struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - u32 val, pf2vf_offset; - u32 total_delay = 0, mdelay = ADF_IOV_MSG_ACK_DELAY_MS, - udelay = ADF_IOV_MSG_ACK_DELAY_US; - u32 local_in_use_mask, local_in_use_pattern; - u32 remote_in_use_mask, remote_in_use_pattern; - struct mutex *lock; /* lock preventing concurrent acces of CSR */ - u32 int_bit; - int ret = 0; - struct pfvf_stats *pfvf_counters = NULL; - - if (accel_dev->is_vf) { - pf2vf_offset = hw_data->get_pf2vf_offset(0); - lock = &accel_dev->u1.vf.vf2pf_lock; - local_in_use_mask = ADF_VF2PF_IN_USE_BY_VF_MASK; - local_in_use_pattern = ADF_VF2PF_IN_USE_BY_VF; - remote_in_use_mask = ADF_PF2VF_IN_USE_BY_PF_MASK; - remote_in_use_pattern = ADF_PF2VF_IN_USE_BY_PF; - int_bit = ADF_VF2PF_INT; - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - } else { - pf2vf_offset = hw_data->get_pf2vf_offset(vf_nr); - lock = &accel_dev->u1.pf.vf_info[vf_nr].pf2vf_lock; - local_in_use_mask = ADF_PF2VF_IN_USE_BY_PF_MASK; - local_in_use_pattern = ADF_PF2VF_IN_USE_BY_PF; - remote_in_use_mask = ADF_VF2PF_IN_USE_BY_VF_MASK; - remote_in_use_pattern = ADF_VF2PF_IN_USE_BY_VF; - int_bit = ADF_PF2VF_INT; - pfvf_counters = &accel_dev->u1.pf.vf_info[vf_nr].pfvf_counters; - } - - mutex_lock(lock); - - /* Check if PF2VF CSR is in use by remote function */ - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - if ((val & remote_in_use_mask) == remote_in_use_pattern) { - device_printf(GET_DEV(accel_dev), - "PF2VF CSR in use by remote function\n"); - ret = EAGAIN; - pfvf_counters->busy++; - goto out; - } - - /* Attempt to get ownership of PF2VF CSR */ - msg &= ~local_in_use_mask; - msg |= local_in_use_pattern; - ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg | int_bit); - pfvf_counters->tx++; - - /* Wait for confirmation from remote func it received the message */ - do { - if (udelay < ADF_IOV_MSG_ACK_EXP_MAX_DELAY_US) { - usleep_range(udelay, udelay * 2); - udelay = udelay * 2; - total_delay = total_delay + udelay; - } else { - pause_ms("adfstop", mdelay); - total_delay = total_delay + (mdelay * 1000); - } - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - } while ((val & int_bit) && - (total_delay < ADF_IOV_MSG_ACK_LIN_MAX_DELAY_US)); - - if (val & int_bit) { - device_printf(GET_DEV(accel_dev), - "ACK not received from remote\n"); - pfvf_counters->no_ack++; - val &= ~int_bit; - ret = EIO; - } - - /* For fire-and-forget notifications, the receiver does not clear - * the in-use pattern. This is used to detect collisions. - */ - if (is_notification && (val & ~int_bit) != msg) { - /* Collision must have overwritten the message */ - device_printf(GET_DEV(accel_dev), - "Collision on notification\n"); - pfvf_counters->collision++; - ret = EAGAIN; - goto out; - } - - /* - * If the far side did not clear the in-use pattern it is either - * 1) Notification - message left intact to detect collision - * 2) Older protocol (compatibility version < 3) on the far side - * where the sender is responsible for clearing the in-use - * pattern after the received has acknowledged receipt. - * In either case, clear the in-use pattern now. - */ - if ((val & local_in_use_mask) == local_in_use_pattern) - ADF_CSR_WR(pmisc_bar_addr, - pf2vf_offset, - val & ~local_in_use_mask); - -out: - mutex_unlock(lock); - return ret; -} - -static int -adf_iov_put(struct adf_accel_dev *accel_dev, - u32 msg, - u8 vf_nr, - bool is_notification) -{ - u32 count = 0, delay = ADF_IOV_MSG_RETRY_DELAY; - int ret; - struct pfvf_stats *pfvf_counters = NULL; - - if (accel_dev->is_vf) - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - else - pfvf_counters = &accel_dev->u1.pf.vf_info[vf_nr].pfvf_counters; - - do { - ret = __adf_iov_putmsg(accel_dev, msg, vf_nr, is_notification); - if (ret == EAGAIN) - pause_ms("adfstop", delay); - delay = delay * 2; - } while (ret == EAGAIN && ++count < ADF_IOV_MSG_MAX_RETRIES); - if (ret == EAGAIN) { - if (is_notification) - pfvf_counters->event_timeout++; - else - pfvf_counters->tx_timeout++; - } - - return ret; -} - -/** - * adf_iov_putmsg() - send PF2VF message - * @accel_dev: Pointer to acceleration device. - * @msg: Message to send - * @vf_nr: VF number to which the message will be sent - * - * Function sends a messge from the PF to a VF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) -{ - return adf_iov_put(accel_dev, msg, vf_nr, false); -} - -/** - * adf_iov_notify() - send PF2VF notification message - * @accel_dev: Pointer to acceleration device. - * @msg: Message to send - * @vf_nr: VF number to which the message will be sent - * - * Function sends a notification messge from the PF to a VF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_iov_notify(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) -{ - return adf_iov_put(accel_dev, msg, vf_nr, true); -} - -u8 -adf_pfvf_crc(u8 start_crc, u8 *buf, u8 len) -{ - u8 crc = start_crc; - - while (len-- > 0) - crc = pfvf_crc8_table[(crc ^ *buf++) & 0xff]; - - return crc; -} - -int -adf_iov_block_provider_register(u8 msg_type, - const adf_iov_block_provider provider) -{ - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - return -EINVAL; - } - if (pf2vf_message_providers[msg_type]) { - pr_err("QAT: Provider %ps already registered for message %d\n", - pf2vf_message_providers[msg_type], - msg_type); - return -EINVAL; - } - - pf2vf_message_providers[msg_type] = provider; - return 0; -} - -u8 -adf_iov_is_block_provider_registered(u8 msg_type) -{ - if (pf2vf_message_providers[msg_type]) - return 1; - else - return 0; -} - -int -adf_iov_block_provider_unregister(u8 msg_type, - const adf_iov_block_provider provider) -{ - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - return -EINVAL; - } - if (pf2vf_message_providers[msg_type] != provider) { - pr_err("QAT: Provider %ps not registered for message %d\n", - provider, - msg_type); - return -EINVAL; - } - - pf2vf_message_providers[msg_type] = NULL; - return 0; -} - -static int -adf_iov_block_get_data(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility, - bool crc) -{ - u8 *buffer; - u8 size; - u8 msg_ver; - u8 crc8; - - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - *data = ADF_PF2VF_INVALID_BLOCK_TYPE; - return -EINVAL; - } - - if (!pf2vf_message_providers[msg_type]) { - pr_err("QAT: No registered provider for message %d\n", - msg_type); - *data = ADF_PF2VF_INVALID_BLOCK_TYPE; - return -EINVAL; - } - - if ((*pf2vf_message_providers[msg_type])( - accel_dev, &buffer, &size, &msg_ver, compatibility, byte_num)) { - pr_err("QAT: unknown error from provider for message %d\n", - msg_type); - *data = ADF_PF2VF_UNSPECIFIED_ERROR; - return -EINVAL; - } - - if ((msg_type <= ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE && - size > ADF_VF2PF_SMALL_PAYLOAD_SIZE) || - (msg_type <= ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE && - size > ADF_VF2PF_MEDIUM_PAYLOAD_SIZE) || - size > ADF_VF2PF_LARGE_PAYLOAD_SIZE) { - pr_err("QAT: Invalid size %d provided for message type %d\n", - size, - msg_type); - *data = ADF_PF2VF_PAYLOAD_TRUNCATED; - return -EINVAL; - } - - if ((!byte_num && crc) || byte_num >= size + ADF_VF2PF_BLOCK_DATA) { - pr_err("QAT: Invalid byte number %d for message %d\n", - byte_num, - msg_type); - *data = ADF_PF2VF_INVALID_BYTE_NUM_REQ; - return -EINVAL; - } - - if (crc) { - crc8 = adf_pfvf_crc(ADF_CRC8_INIT_VALUE, &msg_ver, 1); - crc8 = adf_pfvf_crc(crc8, &size, 1); - *data = adf_pfvf_crc(crc8, buffer, byte_num - 1); - } else { - if (byte_num == 0) - *data = msg_ver; - else if (byte_num == 1) - *data = size; - else - *data = buffer[byte_num - 2]; - } - - return 0; -} - -static int -adf_iov_block_get_byte(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility) -{ - return adf_iov_block_get_data( - accel_dev, msg_type, byte_num, data, compatibility, false); -} - -static int -adf_iov_block_get_crc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility) -{ - return adf_iov_block_get_data( - accel_dev, msg_type, byte_num, data, compatibility, true); -} - -int adf_iov_compatibility_check(struct adf_accel_dev *accel_dev, u8 compat_ver); - -void -adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) -{ - struct adf_accel_dev *accel_dev = vf_info->accel_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - int bar_id = hw_data->get_misc_bar_id(hw_data); - struct adf_bar *pmisc = &GET_BARS(accel_dev)[bar_id]; - struct resource *pmisc_addr = pmisc->virt_addr; - u32 msg, resp = 0, vf_nr = vf_info->vf_nr; - u8 byte_num = 0; - u8 msg_type = 0; - u8 resp_type; - int res; - u8 data; - u8 compat = 0x0; - int vf_compat_ver = 0; - bool is_notification = false; - - /* Read message from the VF */ - msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); - if (!(msg & ADF_VF2PF_INT)) { - device_printf(GET_DEV(accel_dev), - "Spurious VF2PF interrupt. msg %X. Ignored\n", - msg); - vf_info->pfvf_counters.spurious++; - goto out; - } - vf_info->pfvf_counters.rx++; - - if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM)) { - /* Ignore legacy non-system (non-kernel) VF2PF messages */ - device_printf(GET_DEV(accel_dev), - "Ignored non-system message from VF%d (0x%x);\n", - vf_nr + 1, - msg); - /* - * To ack, clear the VF2PFINT bit. - * Because this must be a legacy message, the far side - * must clear the in-use pattern. - */ - msg &= ~(ADF_VF2PF_INT); - ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg); - - goto out; - } - - switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) { - case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ: - - { - is_notification = false; - vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT; - vf_info->compat_ver = vf_compat_ver; - - resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_VERSION_RESP - << ADF_PF2VF_MSGTYPE_SHIFT) | - (ADF_PFVF_COMPATIBILITY_VERSION - << ADF_PF2VF_VERSION_RESP_VERS_SHIFT)); - - device_printf( - GET_DEV(accel_dev), - "Compatibility Version Request from VF%d vers=%u\n", - vf_nr + 1, - vf_info->compat_ver); - - if (vf_compat_ver < ADF_PFVF_COMPATIBILITY_VERSION) - compat = adf_iov_compatibility_check(accel_dev, - vf_compat_ver); - else if (vf_compat_ver == ADF_PFVF_COMPATIBILITY_VERSION) - compat = ADF_PF2VF_VF_COMPATIBLE; - else - compat = ADF_PF2VF_VF_COMPAT_UNKNOWN; - - resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - - if (compat == ADF_PF2VF_VF_INCOMPATIBLE) - device_printf(GET_DEV(accel_dev), - "VF%d and PF are incompatible.\n", - vf_nr + 1); - } break; - case ADF_VF2PF_MSGTYPE_VERSION_REQ: - device_printf(GET_DEV(accel_dev), - "Legacy VersionRequest received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = false; - - /* legacy driver, VF compat_ver is 0 */ - vf_info->compat_ver = 0; - - resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_VERSION_RESP - << ADF_PF2VF_MSGTYPE_SHIFT)); - - /* PF always newer than legacy VF */ - compat = - adf_iov_compatibility_check(accel_dev, vf_info->compat_ver); - resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - - /* Set legacy major and minor version num */ - resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT | - 1 << ADF_PF2VF_MINORVERSION_SHIFT; - - if (compat == ADF_PF2VF_VF_INCOMPATIBLE) - device_printf(GET_DEV(accel_dev), - "VF%d and PF are incompatible.\n", - vf_nr + 1); - break; - case ADF_VF2PF_MSGTYPE_INIT: { - device_printf(GET_DEV(accel_dev), - "Init message received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = true; - vf_info->init = true; - } break; - case ADF_VF2PF_MSGTYPE_SHUTDOWN: { - device_printf(GET_DEV(accel_dev), - "Shutdown message received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = true; - vf_info->init = false; - } break; - case ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ: - case ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ: - case ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ: { - is_notification = false; - switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> - ADF_VF2PF_MSGTYPE_SHIFT) { - case ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_LARGE_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE; - break; - case ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_MEDIUM_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE; - break; - case ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_SMALL_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE; - break; - } - - if (msg >> ADF_VF2PF_BLOCK_REQ_CRC_SHIFT) { - res = adf_iov_block_get_crc(accel_dev, - msg_type, - byte_num, - &data, - vf_info->compat_ver); - if (res) - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_ERROR; - else - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_CRC; - } else { - if (!byte_num) - vf_info->pfvf_counters.blk_tx++; - - res = adf_iov_block_get_byte(accel_dev, - msg_type, - byte_num, - &data, - vf_info->compat_ver); - if (res) - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_ERROR; - else - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_DATA; - } - resp = - (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_BLOCK_RESP << ADF_PF2VF_MSGTYPE_SHIFT) | - (resp_type << ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT) | - (data << ADF_PF2VF_BLOCK_RESP_DATA_SHIFT)); - } break; - default: - device_printf(GET_DEV(accel_dev), - "Unknown message from VF%d (0x%x);\n", - vf_nr + 1, - msg); - } - - /* To ack, clear the VF2PFINT bit and the in-use-by */ - msg &= ~ADF_VF2PF_INT; - /* - * Clear the in-use pattern if the sender won't do it. - * Because the compatibility version must be the first message - * exchanged between the VF and PF, the vf_info->compat_ver must be - * set at this time. - * The in-use pattern is not cleared for notifications so that - * it can be used for collision detection. - */ - if (vf_info->compat_ver >= ADF_PFVF_COMPATIBILITY_FAST_ACK && - !is_notification) - msg &= ~ADF_VF2PF_IN_USE_BY_VF_MASK; - ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg); - - if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) - device_printf(GET_DEV(accel_dev), - "Failed to send response to VF\n"); - -out: - return; -} - -void -adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_vf_info *vf; - u32 msg = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PF2VF_MSGTYPE_SHIFT)); - - int i, num_vfs = accel_dev->u1.pf.num_vfs; - for (i = 0, vf = accel_dev->u1.pf.vf_info; i < num_vfs; i++, vf++) { - if (vf->init && adf_iov_notify(accel_dev, msg, i)) - device_printf(GET_DEV(accel_dev), - "Failed to send restarting msg to VF%d\n", - i); - } -} - -void -adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_vf_info *vf; - int i, num_vfs = accel_dev->u1.pf.num_vfs; - u32 msg = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_FATAL_ERROR << ADF_PF2VF_MSGTYPE_SHIFT)); - - for (i = 0, vf = accel_dev->u1.pf.vf_info; i < num_vfs; i++, vf++) { - if (vf->init && adf_iov_notify(accel_dev, msg, i)) - device_printf( - GET_DEV(accel_dev), - "Failed to send fatal error msg 0x%x to VF%d\n", - msg, - i); - } -} - -int -adf_iov_register_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc) -{ - struct adf_accel_compat_manager *cm = accel_dev->cm; - int num = 0; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ENOMEM; - } - - for (num = 0; num < ADF_COMPAT_CHECKER_MAX; num++) { - if (cm->iov_compat_checkers[num]) { - if (cc == cm->iov_compat_checkers[num]) { - device_printf(GET_DEV(accel_dev), - "QAT: already registered\n"); - return EFAULT; - } - } else { - /* registering the new checker */ - cm->iov_compat_checkers[num] = cc; - break; - } - } - - if (num >= ADF_COMPAT_CHECKER_MAX) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility checkers are overflow.\n"); - return EFAULT; - } - - cm->num_chker = num; - return 0; -} - -int -adf_iov_unregister_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc) -{ - struct adf_accel_compat_manager *cm = accel_dev->cm; - int num = 0; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ENOMEM; - } - num = cm->num_chker - 1; - - if (num < 0) { - device_printf( - GET_DEV(accel_dev), - "QAT: Array 'iov_compat_checkers' may use index value(s) -1\n"); - return EFAULT; - } - if (cc == cm->iov_compat_checkers[num]) { - /* unregistering the given checker */ - cm->iov_compat_checkers[num] = NULL; - } else { - device_printf( - GET_DEV(accel_dev), - "QAT: unregistering not in the registered order\n"); - return EFAULT; - } - - cm->num_chker--; - return 0; -} - -int -adf_iov_init_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm) -{ - if (!(*cm)) { - *cm = malloc(sizeof(**cm), M_QAT, M_WAITOK | M_ZERO); - } else { - /* zero the struct */ - explicit_bzero(*cm, sizeof(**cm)); - } - - return 0; -} - -int -adf_iov_shutdown_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm) -{ - if (*cm) { - free(*cm, M_QAT); - *cm = NULL; - } - return 0; -} - -int -adf_iov_compatibility_check(struct adf_accel_dev *accel_dev, u8 compat_ver) -{ - int compatible = ADF_PF2VF_VF_COMPATIBLE; - int i = 0; - struct adf_accel_compat_manager *cm = accel_dev->cm; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ADF_PF2VF_VF_INCOMPATIBLE; - } - for (i = 0; i < cm->num_chker; i++) { - compatible = cm->iov_compat_checkers[i](accel_dev, compat_ver); - if (compatible == ADF_PF2VF_VF_INCOMPATIBLE) { - device_printf( - GET_DEV(accel_dev), - "QAT: PF and VF are incompatible [checker%d]\n", - i); - break; - } - } - return compatible; -} - -static int -adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) -{ - unsigned long timeout = msecs_to_jiffies(ADF_IOV_MSG_RESP_TIMEOUT); - u32 msg = 0; - int ret = 0; - int comp = 0; - int response_received = 0; - int retry_count = 0; - struct pfvf_stats *pfvf_counters = NULL; - - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - - msg = ADF_VF2PF_MSGORIGIN_SYSTEM; - msg |= ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_VF2PF_MSGTYPE_SHIFT; - msg |= ADF_PFVF_COMPATIBILITY_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT; - BUILD_BUG_ON(ADF_PFVF_COMPATIBILITY_VERSION > 255); - /* Clear communication flag - without that VF will not be waiting for - * the response from host driver, and start sending init. - */ - accel_dev->u1.vf.iov_msg_completion = 0; - do { - /* Send request from VF to PF */ - if (retry_count) - pfvf_counters->retry++; - if (adf_iov_putmsg(accel_dev, msg, 0)) { - device_printf( - GET_DEV(accel_dev), - "Failed to send Compat Version Request.\n"); - return EIO; - } - mutex_lock(&accel_dev->u1.vf.vf2pf_lock); - if (accel_dev->u1.vf.iov_msg_completion == 0 && - sx_sleep(&accel_dev->u1.vf.iov_msg_completion, - &accel_dev->u1.vf.vf2pf_lock.sx, - 0, - "pfver", - timeout) == EWOULDBLOCK) { - /* It's possible that wakeup could be missed */ - if (accel_dev->u1.vf.iov_msg_completion) { - response_received = 1; - } else { - device_printf( - GET_DEV(accel_dev), - "IOV request/response message timeout expired\n"); - } - } else { - response_received = 1; - } - mutex_unlock(&accel_dev->u1.vf.vf2pf_lock); - } while (!response_received && - ++retry_count < ADF_IOV_MSG_RESP_RETRIES); - - if (!response_received) - pfvf_counters->rx_timeout++; - else - pfvf_counters->rx_rsp++; - if (!response_received) - return EIO; - - if (accel_dev->u1.vf.compatible == ADF_PF2VF_VF_COMPAT_UNKNOWN) - /* Response from PF received, check compatibility */ - comp = adf_iov_compatibility_check(accel_dev, - accel_dev->u1.vf.pf_version); - else - comp = accel_dev->u1.vf.compatible; - - ret = (comp == ADF_PF2VF_VF_COMPATIBLE) ? 0 : EFAULT; - if (ret) - device_printf( - GET_DEV(accel_dev), - "VF is not compatible with PF, due to the reason %d\n", - comp); - - return ret; -} - -/** - * adf_enable_vf2pf_comms() - Function enables communication from vf to pf - * - * @accel_dev: Pointer to acceleration device virtual function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - int ret = 0; - - /* init workqueue for VF */ - ret = adf_init_vf_wq(); - if (ret) - return ret; - - adf_enable_pf2vf_interrupts(accel_dev); - adf_iov_init_compat_manager(accel_dev, &accel_dev->cm); - return adf_vf2pf_request_version(accel_dev); -} -/** - * adf_disable_vf2pf_comms() - Function disables communication from vf to pf - * - * @accel_dev: Pointer to acceleration device virtual function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - return adf_iov_shutdown_compat_manager(accel_dev, &accel_dev->cm); -} - -/** - * adf_pf_enable_vf2pf_comms() - Function enables communication from pf - * - * @accel_dev: Pointer to acceleration device physical function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - adf_iov_init_compat_manager(accel_dev, &accel_dev->cm); - return 0; -} - -/** - * adf_pf_disable_vf2pf_comms() - Function disables communication from pf - * - * @accel_dev: Pointer to acceleration device physical function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_pf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - return adf_iov_shutdown_compat_manager(accel_dev, &accel_dev->cm); -} diff --git a/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c b/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c deleted file mode 100644 index 46c130682275..000000000000 --- a/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" -#include "adf_cfg.h" - -#define ADF_VF2PF_RING_TO_SVC_VERSION 1 -#define ADF_VF2PF_RING_TO_SVC_LENGTH 2 - -int -adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num) -{ - static u8 data[ADF_VF2PF_RING_TO_SVC_LENGTH] = { 0 }; - struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev); - u16 ring_to_svc_map = hw_data->ring_to_svc_map; - u16 byte = 0; - - for (byte = 0; byte < ADF_VF2PF_RING_TO_SVC_LENGTH; byte++) { - data[byte] = (ring_to_svc_map >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - *length = ADF_VF2PF_RING_TO_SVC_LENGTH; - *block_version = ADF_VF2PF_RING_TO_SVC_VERSION; - *buffer = data; - - return 0; -} - -int -adf_pf_vf_ring_to_svc_init(struct adf_accel_dev *accel_dev) -{ - u8 data[ADF_VF2PF_RING_TO_SVC_LENGTH] = { 0 }; - u8 len = ADF_VF2PF_RING_TO_SVC_LENGTH; - u8 version = ADF_VF2PF_RING_TO_SVC_VERSION; - u16 ring_to_svc_map = 0; - u16 byte = 0; - - if (!accel_dev->is_vf) { - /* on the pf */ - if (!adf_iov_is_block_provider_registered( - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ)) - adf_iov_block_provider_register( - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ, - adf_pf_ring_to_svc_msg_provider); - } else if (accel_dev->u1.vf.pf_version >= - ADF_PFVF_COMPATIBILITY_RING_TO_SVC_MAP) { - /* on the vf */ - if (adf_iov_block_get(accel_dev, - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ, - &version, - data, - &len)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed adf_iov_block_get\n"); - return EFAULT; - } - for (byte = 0; byte < ADF_VF2PF_RING_TO_SVC_LENGTH; byte++) { - ring_to_svc_map |= data[byte] - << (byte * ADF_PFVF_DATA_SHIFT); - } - GET_HW_DATA(accel_dev)->ring_to_svc_map = ring_to_svc_map; - } - - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_pfvf_utils.c b/sys/dev/qat/qat_common/adf_pfvf_utils.c new file mode 100644 index 000000000000..3c8c729e4569 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_utils.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include "adf_accel_devices.h" +#include "adf_pfvf_msg.h" +#include "adf_pfvf_utils.h" + +/* CRC Calculation */ +#define ADF_CRC8_INIT_VALUE 0xFF + +static const unsigned char pfvf_crc8_table[] = + { 0x00, 0x97, 0xB9, 0x2E, 0xE5, 0x72, 0x5C, 0xCB, 0x5D, 0xCA, 0xE4, 0x73, + 0xB8, 0x2F, 0x01, 0x96, 0xBA, 0x2D, 0x03, 0x94, 0x5F, 0xC8, 0xE6, 0x71, + 0xE7, 0x70, 0x5E, 0xC9, 0x02, 0x95, 0xBB, 0x2C, 0xE3, 0x74, 0x5A, 0xCD, + 0x06, 0x91, 0xBF, 0x28, 0xBE, 0x29, 0x07, 0x90, 0x5B, 0xCC, 0xE2, 0x75, + 0x59, 0xCE, 0xE0, 0x77, 0xBC, 0x2B, 0x05, 0x92, 0x04, 0x93, 0xBD, 0x2A, + 0xE1, 0x76, 0x58, 0xCF, 0x51, 0xC6, 0xE8, 0x7F, 0xB4, 0x23, 0x0D, 0x9A, + 0x0C, 0x9B, 0xB5, 0x22, 0xE9, 0x7E, 0x50, 0xC7, 0xEB, 0x7C, 0x52, 0xC5, + 0x0E, 0x99, 0xB7, 0x20, 0xB6, 0x21, 0x0F, 0x98, 0x53, 0xC4, 0xEA, 0x7D, + 0xB2, 0x25, 0x0B, 0x9C, 0x57, 0xC0, 0xEE, 0x79, 0xEF, 0x78, 0x56, 0xC1, + 0x0A, 0x9D, 0xB3, 0x24, 0x08, 0x9F, 0xB1, 0x26, 0xED, 0x7A, 0x54, 0xC3, + 0x55, 0xC2, 0xEC, 0x7B, 0xB0, 0x27, 0x09, 0x9E, 0xA2, 0x35, 0x1B, 0x8C, + 0x47, 0xD0, 0xFE, 0x69, 0xFF, 0x68, 0x46, 0xD1, 0x1A, 0x8D, 0xA3, 0x34, + 0x18, 0x8F, 0xA1, 0x36, 0xFD, 0x6A, 0x44, 0xD3, 0x45, 0xD2, 0xFC, 0x6B, + 0xA0, 0x37, 0x19, 0x8E, 0x41, 0xD6, 0xF8, 0x6F, 0xA4, 0x33, 0x1D, 0x8A, + 0x1C, 0x8B, 0xA5, 0x32, 0xF9, 0x6E, 0x40, 0xD7, 0xFB, 0x6C, 0x42, 0xD5, + 0x1E, 0x89, 0xA7, 0x30, 0xA6, 0x31, 0x1F, 0x88, 0x43, 0xD4, 0xFA, 0x6D, + 0xF3, 0x64, 0x4A, 0xDD, 0x16, 0x81, 0xAF, 0x38, 0xAE, 0x39, 0x17, 0x80, + 0x4B, 0xDC, 0xF2, 0x65, 0x49, 0xDE, 0xF0, 0x67, 0xAC, 0x3B, 0x15, 0x82, + 0x14, 0x83, 0xAD, 0x3A, 0xF1, 0x66, 0x48, 0xDF, 0x10, 0x87, 0xA9, 0x3E, + 0xF5, 0x62, 0x4C, 0xDB, 0x4D, 0xDA, 0xF4, 0x63, 0xA8, 0x3F, 0x11, 0x86, + 0xAA, 0x3D, 0x13, 0x84, 0x4F, 0xD8, 0xF6, 0x61, 0xF7, 0x60, 0x4E, 0xD9, + 0x12, 0x85, 0xAB, 0x3C }; + +static u8 +adf_pfvf_crc(u8 start_crc, u8 const *buf, u8 len) +{ + u8 crc = start_crc; + + while (len-- > 0) + crc = pfvf_crc8_table[(crc ^ *buf++) & 0xff]; + + return crc; +} + +u8 +adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len) +{ + return adf_pfvf_crc(ADF_CRC8_INIT_VALUE, buf, buf_len); +} + +static bool +set_value_on_csr_msg(struct adf_accel_dev *accel_dev, + u32 *csr_msg, + u32 value, + const struct pfvf_field_format *fmt) +{ + if (unlikely((value & fmt->mask) != value)) { + device_printf( + GET_DEV(accel_dev), + "PFVF message value 0x%X out of range, %u max allowed\n", + value, + fmt->mask); + return false; + } + + *csr_msg |= value << fmt->offset; + + return true; +} + +u32 +adf_pfvf_csr_msg_of(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + const struct pfvf_csr_format *fmt) +{ + u32 csr_msg = 0; + + if (!set_value_on_csr_msg(accel_dev, &csr_msg, msg.type, &fmt->type) || + !set_value_on_csr_msg(accel_dev, &csr_msg, msg.data, &fmt->data)) + return 0; + + return csr_msg | ADF_PFVF_MSGORIGIN_SYSTEM; +} + +struct pfvf_message +adf_pfvf_message_of(struct adf_accel_dev *accel_dev, + u32 csr_msg, + const struct pfvf_csr_format *fmt) +{ + struct pfvf_message msg = { 0 }; + + msg.type = (csr_msg >> fmt->type.offset) & fmt->type.mask; + msg.data = (csr_msg >> fmt->data.offset) & fmt->data.mask; + + if (unlikely(!msg.type)) + device_printf(GET_DEV(accel_dev), + "Invalid PFVF msg with no type received\n"); + + return msg; +} diff --git a/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c b/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c new file mode 100644 index 000000000000..5d4d9044362d --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_pfvf_msg.h" +#include "adf_pfvf_vf_msg.h" +#include "adf_pfvf_vf_proto.h" + +/** + * adf_vf2pf_notify_init() - send init msg to PF + * @accel_dev: Pointer to acceleration VF device. + * + * Function sends an init message from the VF to a PF + * + * Return: 0 on success, error code otherwise. + */ +int +adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT }; + + if (adf_send_vf2pf_msg(accel_dev, msg)) { + device_printf(GET_DEV(accel_dev), + "Failed to send Init event to PF\n"); + return -EFAULT; + } + set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + return 0; +} + +/** + * adf_vf2pf_notify_shutdown() - send shutdown msg to PF + * @accel_dev: Pointer to acceleration VF device. + * + * Function sends a shutdown message from the VF to a PF + * + * Return: void + */ +void +adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_SHUTDOWN }; + + if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status)) + if (adf_send_vf2pf_msg(accel_dev, msg)) + device_printf(GET_DEV(accel_dev), + "Failed to send Shutdown event to PF\n"); +} + +int +adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) +{ + u8 pf_version; + int compat; + int ret; + struct pfvf_message resp; + struct pfvf_message msg = { + .type = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ, + .data = ADF_PFVF_COMPAT_THIS_VERSION, + }; + + BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255); + + ret = adf_send_vf2pf_req(accel_dev, msg, &resp); + if (ret) { + device_printf( + GET_DEV(accel_dev), + "Failed to send Compatibility Version Request.\n"); + return ret; + } + + pf_version = FIELD_GET(ADF_PF2VF_VERSION_RESP_VERS_MASK, resp.data); + compat = FIELD_GET(ADF_PF2VF_VERSION_RESP_RESULT_MASK, resp.data); + + /* Response from PF received, check compatibility */ + switch (compat) { + case ADF_PF2VF_VF_COMPATIBLE: + break; + case ADF_PF2VF_VF_COMPAT_UNKNOWN: + /* VF is newer than PF - compatible for now */ + break; + case ADF_PF2VF_VF_INCOMPATIBLE: + device_printf( + GET_DEV(accel_dev), + "PF (vers %d) and VF (vers %d) are not compatible\n", + pf_version, + ADF_PFVF_COMPAT_THIS_VERSION); + return -EINVAL; + default: + device_printf( + GET_DEV(accel_dev), + "Invalid response from PF; assume not compatible\n"); + return -EINVAL; + } + + accel_dev->u1.vf.pf_compat_ver = pf_version; + return 0; +} + +int +adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + struct capabilities_v3 cap_msg = { 0 }; + unsigned int len = sizeof(cap_msg); + + if (accel_dev->u1.vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES) + /* The PF is too old to support the extended capabilities */ + return 0; + + if (adf_send_vf2pf_blkmsg_req(accel_dev, + ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY, + (u8 *)&cap_msg, + &len)) { + device_printf(GET_DEV(accel_dev), + "QAT: Failed to get block message response\n"); + return -EFAULT; + } + + switch (cap_msg.hdr.version) { + default: + /* Newer version received, handle only the know parts */ + fallthrough; + case ADF_PFVF_CAPABILITIES_V3_VERSION: + if (likely(len >= sizeof(struct capabilities_v3))) + hw_data->clock_frequency = cap_msg.frequency; + else + device_printf(GET_DEV(accel_dev), + "Could not get frequency"); + fallthrough; + case ADF_PFVF_CAPABILITIES_V2_VERSION: + if (likely(len >= sizeof(struct capabilities_v2))) { + hw_data->accel_capabilities_mask = cap_msg.capabilities; + } else { + device_printf(GET_DEV(accel_dev), + "Could not get capabilities"); + } + fallthrough; + case ADF_PFVF_CAPABILITIES_V1_VERSION: + if (likely(len >= sizeof(struct capabilities_v1))) { + hw_data->extended_dc_capabilities = cap_msg.ext_dc_caps; + } else { + device_printf( + GET_DEV(accel_dev), + "Capabilities message truncated to %d bytes\n", + len); + return -EFAULT; + } + } + + return 0; +} + +int +adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev) +{ + struct ring_to_svc_map_v1 rts_map_msg = { 0 }; + unsigned int len = sizeof(rts_map_msg); + + if (accel_dev->u1.vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP) + /* Use already set default mappings */ + return 0; + + if (adf_send_vf2pf_blkmsg_req(accel_dev, + ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP, + (u8 *)&rts_map_msg, + &len)) { + device_printf(GET_DEV(accel_dev), + "QAT: Failed to get block message response\n"); + return -EFAULT; + } + + if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) { + device_printf(GET_DEV(accel_dev), + "RING_TO_SVC message truncated to %d bytes\n", + len); + return -EFAULT; + } + + /* Only v1 at present */ + accel_dev->hw_device->ring_to_svc_map = rts_map_msg.map; + return 0; +} diff --git a/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c b/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c new file mode 100644 index 000000000000..04a5133dd90d --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_pfvf_msg.h" +#include "adf_pfvf_utils.h" +#include "adf_pfvf_vf_msg.h" +#include "adf_pfvf_vf_proto.h" + +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +#define FIELD_MAX(_mask) ({ (typeof(_mask))((_mask) >> __bf_shf(_mask)); }) + +#define FIELD_PREP(_mask, _val) \ + ({ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); }) + +#define FIELD_GET(_mask, _reg) \ + ({ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); }) + +/** + * adf_send_vf2pf_msg() - send VF to PF message + * @accel_dev: Pointer to acceleration device + * @msg: Message to send + * + * This function allows the VF to send a message to the PF. + * + * Return: 0 on success, error code otherwise. + */ +int +adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg) +{ + struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); + u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0); + + int ret = pfvf_ops->send_msg(accel_dev, + msg, + pfvf_offset, + &accel_dev->u1.vf.vf2pf_lock); + return ret; +} + +/** + * adf_recv_pf2vf_msg() - receive a PF to VF message + * @accel_dev: Pointer to acceleration device + * + * This function allows the VF to receive a message from the PF. + * + * Return: a valid message on success, zero otherwise. + */ +static struct pfvf_message +adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev) +{ + struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); + u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0); // 1008 + return pfvf_ops->recv_msg(accel_dev, + pfvf_offset, + accel_dev->u1.vf.pf_compat_ver); +} + +/** + * adf_send_vf2pf_req() - send VF2PF request message + * @accel_dev: Pointer to acceleration device. + * @msg: Request message to send + * @resp: Returned PF response + * + * This function sends a message that requires a response from the VF to the PF + * and waits for a reply. + * + * Return: 0 on success, error code otherwise. + */ +int +adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + struct pfvf_message *resp) +{ + unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT); + unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES; + int ret; + + reinit_completion(&accel_dev->u1.vf.msg_received); + /* Send request from VF to PF */ + do { + ret = adf_send_vf2pf_msg(accel_dev, msg); + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to send request msg to PF\n"); + return ret; + } + + /* Wait for response, if it times out retry */ + ret = + wait_for_completion_timeout(&accel_dev->u1.vf.msg_received, + timeout); + if (ret) { + if (likely(resp)) + *resp = accel_dev->u1.vf.response; + + /* Once copied, set to an invalid value */ + accel_dev->u1.vf.response.type = 0; + + return 0; + } + + device_printf(GET_DEV(accel_dev), + "PFVF response message timeout\n"); + } while (--retries); + + return -EIO; +} + +static int +adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, + bool crc, + u8 *type, + u8 *data) +{ + struct pfvf_message req = { 0 }; + struct pfvf_message resp = { 0 }; + u8 blk_type; + u8 blk_byte; + u8 msg_type; + u8 max_data; + int err; + + /* Convert the block type to {small, medium, large} size category */ + if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) { + msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ; + blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type); + blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data); + max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX; + } else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) { + msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ; + blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, + *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX); + blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data); + max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX; + } else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) { + msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ; + blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, + *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX); + blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data); + max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX; + } else { + device_printf(GET_DEV(accel_dev), + "Invalid message type %u\n", + *type); + return -EINVAL; + } + + /* Sanity check */ + if (*data > max_data) { + device_printf(GET_DEV(accel_dev), + "Invalid byte %s %u for message type %u\n", + crc ? "count" : "index", + *data, + *type); + return -EINVAL; + } + + /* Build the block message */ + req.type = msg_type; + req.data = + blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc); + + err = adf_send_vf2pf_req(accel_dev, req, &resp); + if (err) + return err; + + *type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data); + *data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data); + + return 0; +} + +static int +adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, + u8 type, + u8 index, + u8 *data) +{ + int ret; + + ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index); + if (ret < 0) + return ret; + + if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) { + device_printf(GET_DEV(accel_dev), + "Unexpected BLKMSG response type %u, byte 0x%x\n", + type, + index); + return -EFAULT; + } + + *data = index; + return 0; +} + +static int +adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, + u8 type, + u8 bytes, + u8 *crc) +{ + int ret; + + /* The count of bytes refers to a length, however shift it to a 0-based + * count to avoid overflows. Thus, a request for 0 bytes is technically + * valid. + */ + --bytes; + + ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes); + if (ret < 0) + return ret; + + if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) { + device_printf( + GET_DEV(accel_dev), + "Unexpected CRC BLKMSG response type %u, crc 0x%x\n", + type, + bytes); + return -EFAULT; + } + + *crc = bytes; + return 0; +} + +/** + * adf_send_vf2pf_blkmsg_req() - retrieve block message + * @accel_dev: Pointer to acceleration VF device. + * @type: The block message type, see adf_pfvf_msg.h for allowed values + * @buffer: input buffer where to place the received data + * @buffer_len: buffer length as input, the amount of written bytes on output + * + * Request a message of type 'type' over the block message transport. + * This function will send the required amount block message requests and + * return the overall content back to the caller through the provided buffer. + * The buffer should be large enough to contain the requested message type, + * otherwise the response will be truncated. + * + * Return: 0 on success, error code otherwise. + */ +int +adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, + u8 type, + u8 *buffer, + unsigned int *buffer_len) +{ + unsigned int index; + unsigned int msg_len; + int ret; + u8 remote_crc; + u8 local_crc; + + if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) { + device_printf(GET_DEV(accel_dev), + "Invalid block message type %d\n", + type); + return -EINVAL; + } + + if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) { + device_printf(GET_DEV(accel_dev), + "Buffer size too small for a block message\n"); + return -EINVAL; + } + + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, + type, + ADF_PFVF_BLKMSG_VER_BYTE, + &buffer[ADF_PFVF_BLKMSG_VER_BYTE]); + if (unlikely(ret)) + return ret; + + if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) { + device_printf(GET_DEV(accel_dev), + "Invalid version 0 received for block request %u", + type); + return -EFAULT; + } + + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, + type, + ADF_PFVF_BLKMSG_LEN_BYTE, + &buffer[ADF_PFVF_BLKMSG_LEN_BYTE]); + if (unlikely(ret)) + return ret; + + if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) { + device_printf(GET_DEV(accel_dev), + "Invalid size 0 received for block request %u", + type); + return -EFAULT; + } + + /* We need to pick the minimum since there is no way to request a + * specific version. As a consequence any scenario is possible: + * - PF has a newer (longer) version which doesn't fit in the buffer + * - VF expects a newer (longer) version, so we must not ask for + * bytes in excess + * - PF and VF share the same version, no problem + */ + msg_len = + ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE]; + msg_len = min(*buffer_len, msg_len); + + /* Get the payload */ + for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) { + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, + type, + index, + &buffer[index]); + if (unlikely(ret)) + return ret; + } + + ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc); + if (unlikely(ret)) + return ret; + + local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len); + if (unlikely(local_crc != remote_crc)) { + device_printf( + GET_DEV(accel_dev), + "CRC error on msg type %d. Local %02X, remote %02X\n", + type, + local_crc, + remote_crc); + return -EIO; + } + + *buffer_len = msg_len; + return 0; +} + +static bool +adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg) +{ + switch (msg.type) { + case ADF_PF2VF_MSGTYPE_RESTARTING: + adf_pf2vf_handle_pf_restarting(accel_dev); + return false; + case ADF_PF2VF_MSGTYPE_RP_RESET_RESP: + adf_pf2vf_handle_pf_rp_reset(accel_dev, msg); + return true; + case ADF_PF2VF_MSGTYPE_VERSION_RESP: + case ADF_PF2VF_MSGTYPE_BLKMSG_RESP: + accel_dev->u1.vf.response = msg; + complete(&accel_dev->u1.vf.msg_received); + return true; + default: + device_printf( + GET_DEV(accel_dev), + "Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n", + msg.type, + msg.data); + } + + return false; +} + +bool +adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg; + + msg = adf_recv_pf2vf_msg(accel_dev); + if (msg.type) /* Invalid or no message */ + return adf_handle_pf2vf_msg(accel_dev, msg); + + /* No replies for PF->VF messages at present */ + + return true; +} + +/** + * adf_enable_vf2pf_comms() - Function enables communication from vf to pf + * + * @accel_dev: Pointer to acceleration device virtual function. + * + * Return: 0 on success, error code otherwise. + */ +int +adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + int ret; + + hw_data->enable_pf2vf_interrupt(accel_dev); + + ret = adf_vf2pf_request_version(accel_dev); + if (ret) + return ret; + + ret = adf_vf2pf_get_capabilities(accel_dev); + if (ret) + return ret; + + ret = adf_vf2pf_get_ring_to_svc(accel_dev); + return ret; +} diff --git a/sys/dev/qat/qat_common/adf_transport.c b/sys/dev/qat/qat_common/adf_transport.c index a608cb1c217c..5806f511db07 100644 --- a/sys/dev/qat/qat_common/adf_transport.c +++ b/sys/dev/qat/qat_common/adf_transport.c @@ -74,6 +74,10 @@ static void adf_enable_ring_irq(struct adf_etr_bank_data *bank, u32 ring) { struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev); + u32 enable_int_col_mask = 0; + + if (csr_ops->get_int_col_ctl_enable_mask) + enable_int_col_mask = csr_ops->get_int_col_ctl_enable_mask(); mtx_lock(&bank->lock); bank->irq_mask |= (1 << ring); @@ -83,7 +87,8 @@ adf_enable_ring_irq(struct adf_etr_bank_data *bank, u32 ring) bank->irq_mask); csr_ops->write_csr_int_col_ctl(bank->csr_addr, bank->bank_number, - bank->irq_coalesc_timer); + bank->irq_coalesc_timer | + enable_int_col_mask); } static void @@ -142,9 +147,10 @@ adf_handle_response(struct adf_etr_ring_data *ring, u32 quota) ring->callback((u32 *)msg); atomic_dec(ring->inflights); *msg = ADF_RING_EMPTY_SIG; - ring->head = adf_modulo(ring->head + ADF_MSG_SIZE_TO_BYTES( - ring->msg_size), - ADF_RING_SIZE_MODULO(ring->ring_size)); + ring->head = + adf_modulo(ring->head + + ADF_MSG_SIZE_TO_BYTES(ring->msg_size), + ADF_RING_SIZE_MODULO(ring->ring_size)); msg_counter++; msg = (u32 *)((uintptr_t)ring->base_addr + ring->head); } diff --git a/sys/dev/qat/qat_common/adf_vf2pf_msg.c b/sys/dev/qat/qat_common/adf_vf2pf_msg.c deleted file mode 100644 index bd041c7946ab..000000000000 --- a/sys/dev/qat/qat_common/adf_vf2pf_msg.c +++ /dev/null @@ -1,275 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" - -/** - * adf_vf2pf_init() - send init msg to PF - * @accel_dev: Pointer to acceleration VF device. - * - * Function sends an init messge from the VF to a PF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_vf2pf_init(struct adf_accel_dev *accel_dev) -{ - u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | - (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT)); - if (adf_iov_notify(accel_dev, msg, 0)) { - device_printf(GET_DEV(accel_dev), - "Failed to send Init event to PF\n"); - return -EFAULT; - } - set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - return 0; -} - -/** - * adf_vf2pf_shutdown() - send shutdown msg to PF - * @accel_dev: Pointer to acceleration VF device. - * - * Function sends a shutdown messge from the VF to a PF - * - * Return: void - */ -void -adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) -{ - u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | - (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT)); - mutex_init(&accel_dev->u1.vf.vf2pf_lock); - if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status)) - if (adf_iov_notify(accel_dev, msg, 0)) - device_printf(GET_DEV(accel_dev), - "Failed to send Shutdown event to PF\n"); - mutex_destroy(&accel_dev->u1.vf.vf2pf_lock); -} - -static int -adf_iov_block_get_bc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *data, - int get_crc) -{ - u8 blk_type; - u32 msg; - unsigned long timeout = msecs_to_jiffies(ADF_IOV_MSG_RESP_TIMEOUT); - int response_received = 0; - int retry_count = 0; - - msg = ADF_VF2PF_MSGORIGIN_SYSTEM; - if (get_crc) - msg |= 1 << ADF_VF2PF_BLOCK_REQ_CRC_SHIFT; - - if (msg_type <= ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_SMALL_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT; - } else if (msg_type <= ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_MEDIUM_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type - ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT; - } else if (msg_type <= ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_LARGE_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type - ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT; - } else { - device_printf(GET_DEV(accel_dev), - "Invalid message type %d\n", - msg_type); - } - accel_dev->u1.vf.iov_msg_completion = 0; - do { - /* Send request from VF to PF */ - if (retry_count) - accel_dev->u1.vf.pfvf_counters.retry++; - if (adf_iov_putmsg(accel_dev, msg, 0)) { - device_printf(GET_DEV(accel_dev), - "Failed to send block request to PF\n"); - return EIO; - } - - /* Wait for response */ - mutex_lock(&accel_dev->u1.vf.vf2pf_lock); - if (accel_dev->u1.vf.iov_msg_completion == 0 && - sx_sleep(&accel_dev->u1.vf.iov_msg_completion, - &accel_dev->u1.vf.vf2pf_lock.sx, - 0, - "pfver", - timeout) == EWOULDBLOCK) { - /* It's possible that wakeup could be missed */ - if (accel_dev->u1.vf.iov_msg_completion) { - response_received = 1; - } else { - device_printf( - GET_DEV(accel_dev), - "IOV request/response message timeout expired\n"); - } - } else { - response_received = 1; - } - mutex_unlock(&accel_dev->u1.vf.vf2pf_lock); - } while (!response_received && - ++retry_count < ADF_IOV_MSG_RESP_RETRIES); - - if (!response_received) - accel_dev->u1.vf.pfvf_counters.rx_timeout++; - else - accel_dev->u1.vf.pfvf_counters.rx_rsp++; - - if (!response_received) - return EIO; - - if (accel_dev->u1.vf.pf2vf_block_resp_type != - (get_crc ? ADF_PF2VF_BLOCK_RESP_TYPE_CRC : - ADF_PF2VF_BLOCK_RESP_TYPE_DATA)) { - device_printf( - GET_DEV(accel_dev), - "%sBlock response type %d, data %d, msg %d, index %d\n", - get_crc ? "CRC " : "", - accel_dev->u1.vf.pf2vf_block_resp_type, - accel_dev->u1.vf.pf2vf_block_byte, - msg_type, - msg_index); - return -EIO; - } - *data = accel_dev->u1.vf.pf2vf_block_byte; - return 0; -} - -static int -adf_iov_block_get_byte(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *data) -{ - return adf_iov_block_get_bc(accel_dev, msg_type, msg_index, data, 0); -} - -static int -adf_iov_block_get_crc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *crc) -{ - return adf_iov_block_get_bc(accel_dev, msg_type, msg_index - 1, crc, 1); -} - -int -adf_iov_block_get(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 *block_version, - u8 *buffer, - u8 *length) -{ - u8 buf_size = *length; - u8 payload_len; - u8 remote_crc; - u8 local_crc; - u8 buf_index; - int ret; - - if (msg_type > ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE) { - device_printf(GET_DEV(accel_dev), - "Invalid message type %d\n", - msg_type); - return -EINVAL; - } - - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - ADF_VF2PF_BLOCK_VERSION_BYTE, - block_version); - if (ret) - return ret; - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - ADF_VF2PF_BLOCK_LEN_BYTE, - length); - - if (ret) - return ret; - - payload_len = *length; - - if (buf_size < payload_len) { - device_printf( - GET_DEV(accel_dev), - "Truncating block type %d response from %d to %d bytes\n", - msg_type, - payload_len, - buf_size); - payload_len = buf_size; - } - - /* Get the data */ - for (buf_index = 0; buf_index < payload_len; buf_index++) { - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - buf_index + ADF_VF2PF_BLOCK_DATA, - buffer + buf_index); - if (ret) - return ret; - } - - ret = adf_iov_block_get_crc(accel_dev, - msg_type, - payload_len + ADF_VF2PF_BLOCK_DATA, - &remote_crc); - if (ret) - return ret; - local_crc = adf_pfvf_crc(ADF_CRC8_INIT_VALUE, block_version, 1); - local_crc = adf_pfvf_crc(local_crc, length, 1); - local_crc = adf_pfvf_crc(local_crc, buffer, payload_len); - if (local_crc != remote_crc) { - device_printf( - GET_DEV(accel_dev), - "CRC error on msg type %d. Local %02X, remote %02X\n", - msg_type, - local_crc, - remote_crc); - accel_dev->u1.vf.pfvf_counters.crc_err++; - return EIO; - } - - accel_dev->u1.vf.pfvf_counters.blk_rx++; - *length = payload_len; - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_vf_isr.c b/sys/dev/qat/qat_common/adf_vf_isr.c index 2e92133a0b5f..58142c8c965d 100644 --- a/sys/dev/qat/qat_common/adf_vf_isr.c +++ b/sys/dev/qat/qat_common/adf_vf_isr.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -16,19 +17,17 @@ #include "adf_cfg_common.h" #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" -#include "adf_pf2vf_msg.h" - -#define ADF_VINTSOU_BUN BIT(0) -#define ADF_VINTSOU_PF2VF BIT(1) +#include "adf_pfvf_utils.h" static TASKQUEUE_DEFINE_THREAD(qat_vf); +static TASKQUEUE_DEFINE_THREAD(qat_bank_handler); static struct workqueue_struct *adf_vf_stop_wq; static DEFINE_MUTEX(vf_stop_wq_lock); struct adf_vf_stop_data { struct adf_accel_dev *accel_dev; - struct work_struct vf_stop_work; + struct work_struct work; }; static int @@ -57,135 +56,84 @@ static void adf_dev_stop_async(struct work_struct *work) { struct adf_vf_stop_data *stop_data = - container_of(work, struct adf_vf_stop_data, vf_stop_work); + container_of(work, struct adf_vf_stop_data, work); struct adf_accel_dev *accel_dev = stop_data->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; adf_dev_restarting_notify(accel_dev); adf_dev_stop(accel_dev); adf_dev_shutdown(accel_dev); /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); + hw_data->enable_pf2vf_interrupt(accel_dev); kfree(stop_data); } +int +adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev) +{ + struct adf_vf_stop_data *stop_data; + + clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); + if (!stop_data) { + device_printf(GET_DEV(accel_dev), + "Couldn't schedule stop for vf_%d\n", + accel_dev->accel_id); + return -ENOMEM; + } + stop_data->accel_dev = accel_dev; + INIT_WORK(&stop_data->work, adf_dev_stop_async); + queue_work(adf_vf_stop_wq, &stop_data->work); + + return 0; +} + +int +adf_pf2vf_handle_pf_rp_reset(struct adf_accel_dev *accel_dev, + struct pfvf_message msg) +{ + accel_dev->u1.vf.rpreset_sts = msg.data; + if (accel_dev->u1.vf.rpreset_sts == RPRESET_SUCCESS) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(success) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else if (accel_dev->u1.vf.rpreset_sts == RPRESET_NOT_SUPPORTED) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(not supported) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else if (accel_dev->u1.vf.rpreset_sts == RPRESET_INVAL_BANK) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(invalid bank) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else + device_printf( + GET_DEV(accel_dev), + "rpreset resp(timeout) from PF type:0x%x data:0x%x\nn", + msg.type, + msg.data); + + complete(&accel_dev->u1.vf.msg_received); + + return 0; +} + static void adf_pf2vf_bh_handler(void *data, int pending) { struct adf_accel_dev *accel_dev = data; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct adf_bar *pmisc = - &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; - struct resource *pmisc_bar_addr = pmisc->virt_addr; - u32 msg; - bool is_notification = false; - /* Read the message from PF */ - msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); - if (!(msg & ADF_PF2VF_INT)) { - device_printf(GET_DEV(accel_dev), - "Spurious PF2VF interrupt. msg %X. Ignored\n", - msg); - accel_dev->u1.vf.pfvf_counters.spurious++; - goto out; - } - accel_dev->u1.vf.pfvf_counters.rx++; + if (adf_recv_and_handle_pf2vf_msg(accel_dev)) + /* Re-enable PF2VF interrupts */ + hw_data->enable_pf2vf_interrupt(accel_dev); - if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) { - device_printf(GET_DEV(accel_dev), - "Ignore non-system PF2VF message(0x%x)\n", - msg); - /* - * To ack, clear the VF2PFINT bit. - * Because this must be a legacy message, the far side - * must clear the in-use pattern. - */ - msg &= ~ADF_PF2VF_INT; - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); - goto out; - } - - switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) { - case ADF_PF2VF_MSGTYPE_RESTARTING: { - struct adf_vf_stop_data *stop_data; - - is_notification = true; - - device_printf(GET_DEV(accel_dev), - "Restarting msg received from PF 0x%x\n", - msg); - - clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); - if (!stop_data) { - device_printf(GET_DEV(accel_dev), - "Couldn't schedule stop for vf_%d\n", - accel_dev->accel_id); - goto out; - } - stop_data->accel_dev = accel_dev; - INIT_WORK(&stop_data->vf_stop_work, adf_dev_stop_async); - queue_work(adf_vf_stop_wq, &stop_data->vf_stop_work); - break; - } - case ADF_PF2VF_MSGTYPE_VERSION_RESP: - device_printf(GET_DEV(accel_dev), - "Version resp received from PF 0x%x\n", - msg); - is_notification = false; - accel_dev->u1.vf.pf_version = - (msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >> - ADF_PF2VF_VERSION_RESP_VERS_SHIFT; - accel_dev->u1.vf.compatible = - (msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >> - ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - accel_dev->u1.vf.iov_msg_completion = 1; - wakeup(&accel_dev->u1.vf.iov_msg_completion); - break; - case ADF_PF2VF_MSGTYPE_BLOCK_RESP: - is_notification = false; - accel_dev->u1.vf.pf2vf_block_byte = - (msg & ADF_PF2VF_BLOCK_RESP_DATA_MASK) >> - ADF_PF2VF_BLOCK_RESP_DATA_SHIFT; - accel_dev->u1.vf.pf2vf_block_resp_type = - (msg & ADF_PF2VF_BLOCK_RESP_TYPE_MASK) >> - ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT; - accel_dev->u1.vf.iov_msg_completion = 1; - wakeup(&accel_dev->u1.vf.iov_msg_completion); - break; - case ADF_PF2VF_MSGTYPE_FATAL_ERROR: - device_printf(GET_DEV(accel_dev), - "Fatal error received from PF 0x%x\n", - msg); - is_notification = true; - if (adf_notify_fatal_error(accel_dev)) - device_printf(GET_DEV(accel_dev), - "Couldn't notify fatal error\n"); - break; - default: - device_printf(GET_DEV(accel_dev), - "Unknown PF2VF message(0x%x)\n", - msg); - } - - /* To ack, clear the PF2VFINT bit */ - msg &= ~ADF_PF2VF_INT; - /* - * Clear the in-use pattern if the sender won't do it. - * Because the compatibility version must be the first message - * exchanged between the VF and PF, the pf.version must be - * set at this time. - * The in-use pattern is not cleared for notifications so that - * it can be used for collision detection. - */ - if (accel_dev->u1.vf.pf_version >= ADF_PFVF_COMPATIBILITY_FAST_ACK && - !is_notification) - msg &= ~ADF_PF2VF_IN_USE_BY_PF_MASK; - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); - -out: - /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); return; } @@ -211,46 +159,86 @@ adf_cleanup_pf2vf_bh(struct adf_accel_dev *accel_dev) mutex_destroy(&accel_dev->u1.vf.vf2pf_lock); } +static void +adf_bh_handler(void *data, int pending) +{ + struct adf_etr_bank_data *bank = (void *)data; + + adf_response_handler((uintptr_t)bank); + + return; +} + +static int +adf_setup_bh(struct adf_accel_dev *accel_dev) +{ + int i = 0; + struct adf_etr_data *priv_data = accel_dev->transport; + + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + TASK_INIT(&priv_data->banks[i].resp_handler, + 0, + adf_bh_handler, + &priv_data->banks[i]); + } + + return 0; +} + +static void +adf_cleanup_bh(struct adf_accel_dev *accel_dev) +{ + int i = 0; + struct adf_etr_data *transport; + + if (!accel_dev || !accel_dev->transport) + return; + + transport = accel_dev->transport; + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + taskqueue_cancel(taskqueue_qat_bank_handler, + &transport->banks[i].resp_handler, + NULL); + taskqueue_drain(taskqueue_qat_bank_handler, + &transport->banks[i].resp_handler); + } +} + static void adf_isr(void *privdata) { struct adf_accel_dev *accel_dev = privdata; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct adf_bar *pmisc = - &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; - struct resource *pmisc_bar_addr = pmisc->virt_addr; - u32 v_int, v_mask; - int handled = 0; - - /* Read VF INT source CSR to determine the source of VF interrupt */ - v_int = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_vintsou_offset()); - v_mask = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_vintmsk_offset(0)); + struct adf_hw_csr_ops *csr_ops = &hw_data->csr_info.csr_ops; + int int_active_bundles = 0; + int i = 0; /* Check for PF2VF interrupt */ - if ((v_int & ~v_mask) & ADF_VINTSOU_PF2VF) { + if (hw_data->interrupt_active_pf2vf(accel_dev)) { /* Disable PF to VF interrupt */ - adf_disable_pf2vf_interrupts(accel_dev); - + hw_data->disable_pf2vf_interrupt(accel_dev); /* Schedule tasklet to handle interrupt BH */ taskqueue_enqueue(taskqueue_qat_vf, &accel_dev->u1.vf.pf2vf_bh_tasklet); - handled = 1; } - if ((v_int & ~v_mask) & ADF_VINTSOU_BUN) { - struct adf_etr_data *etr_data = accel_dev->transport; - struct adf_etr_bank_data *bank = &etr_data->banks[0]; + if (hw_data->get_int_active_bundles) + int_active_bundles = hw_data->get_int_active_bundles(accel_dev); - /* Disable Flag and Coalesce Ring Interrupts */ - WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, - bank->bank_number, - 0); - adf_response_handler((uintptr_t)&etr_data->banks[0]); - handled = 1; + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + if (int_active_bundles & BIT(i)) { + struct adf_etr_data *etr_data = accel_dev->transport; + struct adf_etr_bank_data *bank = &etr_data->banks[i]; + + /* Disable Flag and Coalesce Ring Interrupts */ + csr_ops->write_csr_int_flag_and_col(bank->csr_addr, + bank->bank_number, + 0); + /* Schedule tasklet to handle interrupt BH */ + taskqueue_enqueue(taskqueue_qat_bank_handler, + &bank->resp_handler); + } } - - if (handled) - return; } static int @@ -259,6 +247,8 @@ adf_request_msi_irq(struct adf_accel_dev *accel_dev) device_t pdev = accel_to_pci_dev(accel_dev); int ret; int rid = 1; + int cpu; + accel_dev->u1.vf.irq = bus_alloc_resource_any(pdev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (accel_dev->u1.vf.irq == NULL) { @@ -273,23 +263,24 @@ adf_request_msi_irq(struct adf_accel_dev *accel_dev) accel_dev, &accel_dev->u1.vf.cookie); if (ret) { - device_printf(GET_DEV(accel_dev), - "failed to enable irq for %s\n", - accel_dev->u1.vf.irq_name); - return ret; + device_printf(GET_DEV(accel_dev), "failed to enable irq\n"); + goto errout; } + + cpu = accel_dev->accel_id % num_online_cpus(); + ret = bus_bind_intr(pdev, accel_dev->u1.vf.irq, cpu); + if (ret) { + device_printf(GET_DEV(accel_dev), + "failed to bind IRQ handler to cpu core\n"); + goto errout; + } + accel_dev->u1.vf.irq_enabled = true; + return ret; -} +errout: + bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); -static int -adf_setup_bh(struct adf_accel_dev *accel_dev) -{ - return 0; -} - -static void -adf_cleanup_bh(struct adf_accel_dev *accel_dev) -{ + return ret; } /** @@ -302,8 +293,13 @@ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev) { device_t pdev = accel_to_pci_dev(accel_dev); - bus_teardown_intr(pdev, accel_dev->u1.vf.irq, accel_dev->u1.vf.cookie); - bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); + + if (accel_dev->u1.vf.irq_enabled) { + bus_teardown_intr(pdev, + accel_dev->u1.vf.irq, + accel_dev->u1.vf.cookie); + bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); + } adf_cleanup_bh(accel_dev); adf_cleanup_pf2vf_bh(accel_dev); adf_disable_msi(accel_dev); @@ -324,30 +320,39 @@ adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev) goto err_out; if (adf_setup_pf2vf_bh(accel_dev)) - goto err_out; + goto err_disable_msi; if (adf_setup_bh(accel_dev)) goto err_out; if (adf_request_msi_irq(accel_dev)) - goto err_out; + goto err_disable_msi; return 0; + +err_disable_msi: + adf_disable_msi(accel_dev); + err_out: - adf_vf_isr_resource_free(accel_dev); - return EFAULT; + return -EFAULT; } /** * adf_flush_vf_wq() - Flush workqueue for VF + * @accel_dev: Pointer to acceleration device. * - * Function flushes workqueue 'adf_vf_stop_wq' for VF. + * Function disables the PF/VF interrupts on the VF so that no new messages + * are received and flushes the workqueue 'adf_vf_stop_wq'. * * Return: void. */ void -adf_flush_vf_wq(void) +adf_flush_vf_wq(struct adf_accel_dev *accel_dev) { + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + hw_data->disable_pf2vf_interrupt(accel_dev); + if (adf_vf_stop_wq) flush_workqueue(adf_vf_stop_wq); } @@ -376,18 +381,11 @@ adf_init_vf_wq(void) return ret; } -/** - * adf_exit_vf_wq() - Destroy workqueue for VF - * - * Function destroy workqueue 'adf_vf_stop_wq' for VF. - * - * Return: void. - */ void adf_exit_vf_wq(void) { - if (adf_vf_stop_wq) { + if (adf_vf_stop_wq) destroy_workqueue(adf_vf_stop_wq); - adf_vf_stop_wq = NULL; - } + + adf_vf_stop_wq = NULL; } diff --git a/sys/dev/qat/qat_common/qat_common_module.c b/sys/dev/qat/qat_common/qat_common_module.c index 93abbbf16433..722575192c51 100644 --- a/sys/dev/qat/qat_common/qat_common_module.c +++ b/sys/dev/qat/qat_common/qat_common_module.c @@ -13,6 +13,9 @@ qat_common_register(void) if (adf_init_fatal_error_wq()) return EFAULT; + if (adf_register_ctl_device_driver()) + return EFAULT; + return 0; } @@ -22,7 +25,7 @@ qat_common_unregister(void) adf_exit_vf_wq(); adf_exit_aer(); adf_exit_fatal_error_wq(); - adf_clean_vf_map(false); + adf_unregister_ctl_device_driver(); } static int diff --git a/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c b/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c index 5bfe1c7f40b3..74ba6cdbc2ec 100644 --- a/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_200xx_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -143,18 +144,6 @@ adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev, *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_200XX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_200XX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -489,8 +478,6 @@ adf_init_hw_data_200xx(struct adf_hw_device_data *hw_data) hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -509,11 +496,8 @@ adf_init_hw_data_200xx(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->measure_clock = measure_clock; hw_data->get_ae_clock = get_ae_clock; hw_data->reset_device = adf_reset_flr; @@ -536,6 +520,7 @@ adf_init_hw_data_200xx(struct adf_hw_device_data *hw_data) hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c index 002ea6d5d876..20b38394263b 100644 --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c @@ -6,8 +6,10 @@ #include #include #include -#include +#include #include +#include +#include #include "adf_4xxx_hw_data.h" #include "adf_heartbeat.h" #include "icp_qat_fw_init_admin.h" @@ -85,17 +87,17 @@ struct adf_enabled_services { u16 rng_to_svc_msk; }; -static struct adf_enabled_services adf_4xxx_svcs[] = { - { "dc", ADF_4XXX_DC }, - { "sym", ADF_4XXX_SYM }, - { "asym", ADF_4XXX_ASYM }, - { "dc;asym", ADF_4XXX_ASYM_DC }, - { "asym;dc", ADF_4XXX_ASYM_DC }, - { "sym;dc", ADF_4XXX_SYM_DC }, - { "dc;sym", ADF_4XXX_SYM_DC }, - { "asym;sym", ADF_4XXX_ASYM_SYM }, - { "sym;asym", ADF_4XXX_ASYM_SYM }, -}; +static struct adf_enabled_services adf_4xxx_svcs[] = + { { "dc", ADF_4XXX_DC }, + { "sym", ADF_4XXX_SYM }, + { "asym", ADF_4XXX_ASYM }, + { "dc;asym", ADF_4XXX_ASYM_DC }, + { "asym;dc", ADF_4XXX_ASYM_DC }, + { "sym;dc", ADF_4XXX_SYM_DC }, + { "dc;sym", ADF_4XXX_SYM_DC }, + { "asym;sym", ADF_4XXX_ASYM_SYM }, + { "sym;asym", ADF_4XXX_ASYM_SYM }, + { "cy", ADF_4XXX_ASYM_SYM } }; static struct adf_hw_device_class adf_4xxx_class = { .name = ADF_4XXX_DEVICE_NAME, @@ -117,6 +119,12 @@ get_ae_mask(struct adf_accel_dev *accel_dev) return ~fusectl4 & ADF_4XXX_ACCELENGINES_MASK; } +static void +adf_set_asym_rings_mask(struct adf_accel_dev *accel_dev) +{ + accel_dev->hw_device->asym_rings_mask = ADF_4XXX_DEF_ASYM_MASK; +} + static int get_ring_to_svc_map(struct adf_accel_dev *accel_dev, u16 *ring_to_svc_map) { @@ -216,28 +224,45 @@ adf_4xxx_get_hw_cap(struct adf_accel_dev *accel_dev) ICP_ACCEL_CAPABILITIES_COMPRESSION | ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION | ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION | - ICP_ACCEL_CAPABILITIES_HKDF | ICP_ACCEL_CAPABILITIES_SHA3_EXT | - ICP_ACCEL_CAPABILITIES_SM3 | ICP_ACCEL_CAPABILITIES_SM4 | - ICP_ACCEL_CAPABILITIES_CHACHA_POLY | - ICP_ACCEL_CAPABILITIES_AESGCM_SPC | - ICP_ACCEL_CAPABILITIES_AES_V2 | ICP_ACCEL_CAPABILITIES_RL; + ICP_ACCEL_CAPABILITIES_SHA3 | ICP_ACCEL_CAPABILITIES_HKDF | + ICP_ACCEL_CAPABILITIES_SHA3_EXT | ICP_ACCEL_CAPABILITIES_SM3 | + ICP_ACCEL_CAPABILITIES_SM4 | ICP_ACCEL_CAPABILITIES_CHACHA_POLY | + ICP_ACCEL_CAPABILITIES_AESGCM_SPC | ICP_ACCEL_CAPABILITIES_AES_V2 | + ICP_ACCEL_CAPABILITIES_RL | ICP_ACCEL_CAPABILITIES_ECEDMONT | + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_HKDF; capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; } - if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) + if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; - if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) + capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3; + capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } + if (fusectl1 & ICP_ACCEL_MASK_PKE_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT; + } if (fusectl1 & ICP_ACCEL_4XXX_MASK_COMPRESS_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; + capabilities &= ~ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION; + capabilities &= ~ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION; capabilities &= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; } if (fusectl1 & ICP_ACCEL_4XXX_MASK_SMX_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_SM3; capabilities &= ~ICP_ACCEL_CAPABILITIES_SM4; } + if (fusectl1 & ICP_ACCEL_4XXX_MASK_UCS_SLICE) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY; + capabilities &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_AES_V2; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } + return capabilities; } @@ -388,15 +413,18 @@ get_accel_unit_config(struct adf_accel_dev *accel_dev, if (!*num_sym_au || !(service_mask & ADF_ACCEL_CRYPTO)) { disabled_caps = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | ICP_ACCEL_CAPABILITIES_CIPHER | + ICP_ACCEL_CAPABILITIES_SHA3 | ICP_ACCEL_CAPABILITIES_SHA3_EXT | - ICP_ACCEL_CAPABILITIES_SM3 | ICP_ACCEL_CAPABILITIES_SM4 | + ICP_ACCEL_CAPABILITIES_HKDF | ICP_ACCEL_CAPABILITIES_SM3 | + ICP_ACCEL_CAPABILITIES_SM4 | ICP_ACCEL_CAPABILITIES_CHACHA_POLY | ICP_ACCEL_CAPABILITIES_AESGCM_SPC | - ICP_ACCEL_CAPABILITIES_AES_V2; + ICP_ACCEL_CAPABILITIES_AES_V2 | + ICP_ACCEL_CAPABILITIES_AUTHENTICATION; } if (!*num_asym_au || !(service_mask & ADF_ACCEL_ASYM)) { disabled_caps |= ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | - ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + ICP_ACCEL_CAPABILITIES_ECEDMONT; } if (!*num_dc_au || !(service_mask & ADF_ACCEL_COMPRESSION)) { disabled_caps |= ICP_ACCEL_CAPABILITIES_COMPRESSION | @@ -771,6 +799,7 @@ adf_4xxx_cfg_gen_dispatch_arbiter(struct adf_accel_dev *accel_dev, u16 service_type; u32 service_mask; unsigned long thd_srv_mask = default_active_thd_mask; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; ena_srv_mask = accel_dev->hw_device->ring_to_svc_map; /* If ring_to_svc_map is not changed, return default arbiter value */ @@ -798,6 +827,8 @@ adf_4xxx_cfg_gen_dispatch_arbiter(struct adf_accel_dev *accel_dev, if (au->services == ADF_ACCEL_COMPRESSION) thd_srv_mask = dc_me_active_thd_mask; + else if (au->services == ADF_ACCEL_ASYM) + thd_srv_mask = hw_data->asym_ae_active_thd_mask; else thd_srv_mask = default_active_thd_mask; @@ -901,7 +932,7 @@ adf_init_device(struct adf_accel_dev *accel_dev) } void -adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) +adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 id) { hw_data->dev_class = &adf_4xxx_class; hw_data->instance_id = adf_4xxx_class.instances++; @@ -954,16 +985,28 @@ adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) hw_data->set_msix_rttable = set_msix_default_rttable; hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer; hw_data->disable_iov = adf_disable_sriov; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->config_device = adf_config_device; - hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; + hw_data->set_asym_rings_mask = adf_set_asym_rings_mask; hw_data->get_hb_clock = get_hb_clock; + hw_data->int_timer_init = adf_int_timer_init; + hw_data->int_timer_exit = adf_int_timer_exit; hw_data->get_heartbeat_status = adf_get_heartbeat_status; hw_data->get_ae_clock = get_ae_clock; hw_data->measure_clock = measure_clock; hw_data->query_storage_cap = 1; + hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; + + switch (id) { + case ADF_401XX_PCI_DEVICE_ID: + hw_data->asym_ae_active_thd_mask = DEFAULT_401XX_ASYM_AE_MASK; + break; + case ADF_4XXX_PCI_DEVICE_ID: + default: + hw_data->asym_ae_active_thd_mask = DEFAULT_4XXX_ASYM_AE_MASK; + } adf_gen4_init_hw_csr_info(&hw_data->csr_info); + adf_gen4_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h index c3e9750e2b17..0d1f8d8c833d 100644 --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h @@ -6,6 +6,9 @@ #include +#define DEFAULT_4XXX_ASYM_AE_MASK 0x03 +#define DEFAULT_401XX_ASYM_AE_MASK 0x3F + /* PCIe configuration space */ #define ADF_4XXX_SRAM_BAR 0 #define ADF_4XXX_PMISC_BAR 1 @@ -56,6 +59,7 @@ #define ADF_4XXX_ERRMSK3 (0x41A21C) #define ADF_4XXX_VFLNOTIFY BIT(7) +#define ADF_4XXX_DEF_ASYM_MASK 0x1 /* Arbiter configuration */ #define ADF_4XXX_ARB_CONFIG (BIT(31) | BIT(6) | BIT(0)) @@ -105,7 +109,7 @@ enum icp_qat_4xxx_slice_mask { ICP_ACCEL_4XXX_MASK_SMX_SLICE = BIT(6), }; -void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data); +void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 id); void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data); #endif diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c b/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c index 76dcf7b37dee..f131f6359296 100644 --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c @@ -91,12 +91,12 @@ adf_attach(device_t dev) int ret, rid; struct adf_cfg_device *cfg_dev = NULL; - /* Set pci MaxPayLoad to 256. Implemented to avoid the issue of + /* Set pci MaxPayLoad to 512. Implemented to avoid the issue of * Pci-passthrough causing Maxpayload to be reset to 128 bytes * when the device is reset. */ - if (pci_get_max_payload(dev) != 256) - pci_set_max_payload(dev, 256); + if (pci_get_max_payload(dev) != 512) + pci_set_max_payload(dev, 512); accel_dev = device_get_softc(dev); @@ -119,7 +119,7 @@ adf_attach(device_t dev) hw_data = malloc(sizeof(*hw_data), M_QAT_4XXX, M_WAITOK | M_ZERO); accel_dev->hw_device = hw_data; - adf_init_hw_data_4xxx(accel_dev->hw_device); + adf_init_hw_data_4xxx(accel_dev->hw_device, pci_get_device(dev)); accel_pci_dev->revid = pci_get_revid(dev); hw_data->fuses = pci_read_config(dev, ADF_4XXX_FUSECTL4_OFFSET, 4); if (accel_pci_dev->revid == 0x00) { @@ -154,7 +154,7 @@ adf_attach(device_t dev) if (ret) goto out_err; - pci_set_max_read_req(dev, 1024); + pci_set_max_read_req(dev, 4096); ret = bus_dma_tag_create(bus_get_dma_tag(dev), 1, diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c new file mode 100644 index 000000000000..add271accb7d --- /dev/null +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include +#include +#include +#include "adf_4xxxvf_hw_data.h" +#include "icp_qat_hw.h" +#include "adf_transport_internal.h" +#include "adf_pfvf_vf_proto.h" + +static struct adf_hw_device_class adf_4xxxiov_class = + { .name = ADF_4XXXVF_DEVICE_NAME, .type = DEV_4XXXVF, .instances = 0 }; + +#define ADF_4XXXIOV_DEFAULT_RING_TO_SRV_MAP \ + (ASYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM_SYM ADF_4XXXIOV_DEFAULT_RING_TO_SRV_MAP + +#define ADF_4XXXIOV_DC \ + (COMP | COMP << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_SYM \ + (SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM \ + (ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM_DC \ + (ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_SYM_DC \ + (SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_NA \ + (NA | NA << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + NA << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + NA << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +struct adf_enabled_services { + const char svcs_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + u16 rng_to_svc_msk; +}; + +static struct adf_enabled_services adf_4xxxiov_svcs[] = + { { "dc", ADF_4XXXIOV_DC }, + { "sym", ADF_4XXXIOV_SYM }, + { "asym", ADF_4XXXIOV_ASYM }, + { "dc;asym", ADF_4XXXIOV_ASYM_DC }, + { "asym;dc", ADF_4XXXIOV_ASYM_DC }, + { "sym;dc", ADF_4XXXIOV_SYM_DC }, + { "dc;sym", ADF_4XXXIOV_SYM_DC }, + { "asym;sym", ADF_4XXXIOV_ASYM_SYM }, + { "sym;asym", ADF_4XXXIOV_ASYM_SYM }, + { "cy", ADF_4XXXIOV_ASYM_SYM } }; + +static u32 +get_accel_mask(struct adf_accel_dev *accel_dev) +{ + return ADF_4XXXIOV_ACCELERATORS_MASK; +} + +static u32 +get_ae_mask(struct adf_accel_dev *accel_dev) +{ + return ADF_4XXXIOV_ACCELENGINES_MASK; +} + +static u32 +get_num_accels(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_MAX_ACCELERATORS; +} + +static u32 +get_num_aes(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_MAX_ACCELENGINES; +} + +static u32 +get_misc_bar_id(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_PMISC_BAR; +} + +static u32 +get_etr_bar_id(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_ETR_BAR; +} + +static u32 +get_clock_speed(struct adf_hw_device_data *self) +{ + /* CPP clock is half high-speed clock */ + return self->clock_frequency / 2; +} + +static enum dev_sku_info +get_sku(struct adf_hw_device_data *self) +{ + return DEV_SKU_VF; +} + +static int +adf_vf_int_noop(struct adf_accel_dev *accel_dev) +{ + return 0; +} + +static void +adf_vf_void_noop(struct adf_accel_dev *accel_dev) +{ +} + +u32 +adf_4xxxvf_get_hw_cap(struct adf_accel_dev *accel_dev) +{ + device_t pdev = accel_dev->accel_pci_dev.pci_dev; + u32 vffusectl1; + u32 capabilities; + + capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC + + ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC + + ICP_ACCEL_CAPABILITIES_CIPHER + + ICP_ACCEL_CAPABILITIES_AUTHENTICATION + + ICP_ACCEL_CAPABILITIES_COMPRESSION + + ICP_ACCEL_CAPABILITIES_SHA3_EXT + ICP_ACCEL_CAPABILITIES_SM2 + + ICP_ACCEL_CAPABILITIES_SM3 + ICP_ACCEL_CAPABILITIES_SM4 + + ICP_ACCEL_CAPABILITIES_CHACHA_POLY + + ICP_ACCEL_CAPABILITIES_AESGCM_SPC + + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64 + + ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION + + ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION; + + /* Get fused capabilities */ + vffusectl1 = pci_read_config(pdev, ADF_4XXXIOV_VFFUSECTL1_OFFSET, 4); + + if (vffusectl1 & BIT(7)) { + capabilities &= + ~(ICP_ACCEL_CAPABILITIES_SM3 + ICP_ACCEL_CAPABILITIES_SM4); + } + if (vffusectl1 & BIT(6)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_SM3; + } + if (vffusectl1 & BIT(3)) { + capabilities &= ~(ICP_ACCEL_CAPABILITIES_COMPRESSION + + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64); + } + if (vffusectl1 & BIT(2)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + } + if (vffusectl1 & BIT(1)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + } + if (vffusectl1 & BIT(0)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } + return capabilities; +} + +static void +adf_set_asym_rings_mask(struct adf_accel_dev *accel_dev) +{ + accel_dev->hw_device->asym_rings_mask = ADF_4XXX_DEF_ASYM_MASK; +} + +static void +enable_pf2vm_interrupt(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + ADF_CSR_WR(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET, 0x0); +} + +static void +disable_pf2vm_interrupt(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + ADF_CSR_WR(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET, BIT(0)); +} + +static int +interrupt_active_pf2vm(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + u32 v_sou, v_msk; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + v_sou = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTSOUPF2VM_OFFSET); + v_msk = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET); + + return ((v_sou & ~v_msk) & BIT(0)) ? 1 : 0; +} + +static int +get_int_active_bundles(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + u32 v_sou, v_msk; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + v_sou = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTSOU_OFFSET); + v_msk = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTMSK_OFFSET); + + return v_sou & ~v_msk & 0xF; +} + +static void +get_ring_svc_map_data(int ring_pair_index, + u16 ring_to_svc_map, + u8 *serv_type, + int *ring_index, + int *num_rings_per_srv, + int bank_num) +{ + *serv_type = + GET_SRV_TYPE(ring_to_svc_map, bank_num % ADF_CFG_NUM_SERVICES); + *ring_index = 0; + *num_rings_per_srv = ADF_4XXXIOV_NUM_RINGS_PER_BANK / 2; +} + +static int +get_ring_to_svc_map(struct adf_accel_dev *accel_dev, u16 *ring_to_svc_map) +{ + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char val[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + u32 i = 0; + + /* Get the services enabled by user if provided. + * The function itself will also be called during the driver probe + * procedure where no ServicesEnable is provided. Then the device + * should still start with default configuration without + * ServicesEnable. Hence it still returns 0 when the + * adf_cfg_get_param_value() function returns failure. + */ + snprintf(key, sizeof(key), ADF_SERVICES_ENABLED); + if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) + return 0; + + for (i = 0; i < ARRAY_SIZE(adf_4xxxiov_svcs); i++) { + if (!strncmp(val, + adf_4xxxiov_svcs[i].svcs_enabled, + ADF_CFG_MAX_KEY_LEN_IN_BYTES)) { + *ring_to_svc_map = adf_4xxxiov_svcs[i].rng_to_svc_msk; + return 0; + } + } + + device_printf(GET_DEV(accel_dev), + "Invalid services enabled: %s\n", + val); + return EFAULT; +} + +static int +adf_4xxxvf_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number) +{ + struct pfvf_message req = { 0 }; + unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT); + int ret = 0; + + if (bank_number >= accel_dev->hw_device->num_banks) + return EINVAL; + + req.type = ADF_VF2PF_MSGTYPE_RP_RESET; + req.data = bank_number; + mutex_lock(&accel_dev->u1.vf.rpreset_lock); + init_completion(&accel_dev->u1.vf.msg_received); + accel_dev->u1.vf.rpreset_sts = RPRESET_SUCCESS; + if (adf_send_vf2pf_msg(accel_dev, req)) { + device_printf(GET_DEV(accel_dev), + "vf ring pair reset failure (vf2pf msg error)\n"); + ret = EFAULT; + goto out; + } + if (!wait_for_completion_timeout(&accel_dev->u1.vf.msg_received, + timeout)) { + device_printf( + GET_DEV(accel_dev), + "vf ring pair reset failure (pf2vf msg timeout)\n"); + ret = EFAULT; + goto out; + } + if (accel_dev->u1.vf.rpreset_sts != RPRESET_SUCCESS) { + device_printf( + GET_DEV(accel_dev), + "vf ring pair reset failure (pf reports error)\n"); + ret = EFAULT; + goto out; + } + +out: + mutex_unlock(&accel_dev->u1.vf.rpreset_lock); + return ret; +} + +void +adf_init_hw_data_4xxxiov(struct adf_hw_device_data *hw_data) +{ + hw_data->dev_class = &adf_4xxxiov_class; + hw_data->num_banks = ADF_4XXXIOV_ETR_MAX_BANKS; + hw_data->num_rings_per_bank = ADF_4XXXIOV_NUM_RINGS_PER_BANK; + hw_data->num_accel = ADF_4XXXIOV_MAX_ACCELERATORS; + hw_data->num_logical_accel = 1; + hw_data->num_engines = ADF_4XXXIOV_MAX_ACCELENGINES; + hw_data->tx_rx_gap = ADF_4XXXIOV_RX_RINGS_OFFSET; + hw_data->tx_rings_mask = ADF_4XXXIOV_TX_RINGS_MASK; + hw_data->ring_to_svc_map = ADF_4XXXIOV_DEFAULT_RING_TO_SRV_MAP; + hw_data->alloc_irq = adf_vf_isr_resource_alloc; + hw_data->free_irq = adf_vf_isr_resource_free; + hw_data->enable_error_correction = adf_vf_void_noop; + hw_data->init_admin_comms = adf_vf_int_noop; + hw_data->exit_admin_comms = adf_vf_void_noop; + hw_data->send_admin_init = adf_vf2pf_notify_init; + hw_data->init_arb = adf_vf_int_noop; + hw_data->exit_arb = adf_vf_void_noop; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; + hw_data->get_accel_mask = get_accel_mask; + hw_data->get_ae_mask = get_ae_mask; + hw_data->get_num_accels = get_num_accels; + hw_data->get_num_aes = get_num_aes; + hw_data->get_etr_bar_id = get_etr_bar_id; + hw_data->get_misc_bar_id = get_misc_bar_id; + hw_data->get_clock_speed = get_clock_speed; + hw_data->get_sku = get_sku; + hw_data->enable_ints = adf_vf_void_noop; + hw_data->reset_device = adf_reset_flr; + hw_data->restore_device = adf_dev_restore; + hw_data->get_ring_svc_map_data = get_ring_svc_map_data; + hw_data->get_ring_to_svc_map = get_ring_to_svc_map; + hw_data->get_accel_cap = adf_4xxxvf_get_hw_cap; + hw_data->config_device = adf_config_device; + hw_data->set_asym_rings_mask = adf_set_asym_rings_mask; + hw_data->ring_pair_reset = adf_4xxxvf_ring_pair_reset; + hw_data->enable_pf2vf_interrupt = enable_pf2vm_interrupt; + hw_data->disable_pf2vf_interrupt = disable_pf2vm_interrupt; + hw_data->interrupt_active_pf2vf = interrupt_active_pf2vm; + hw_data->get_int_active_bundles = get_int_active_bundles; + hw_data->dev_class->instances++; + adf_devmgr_update_class_index(hw_data); + gen4vf_init_hw_csr_info(&hw_data->csr_info); + adf_gen4_init_vf_pfvf_ops(&hw_data->csr_info.pfvf_ops); +} + +void +adf_clean_hw_data_4xxxiov(struct adf_hw_device_data *hw_data) +{ + hw_data->dev_class->instances--; + adf_devmgr_update_class_index(hw_data); +} diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h new file mode 100644 index 000000000000..30877e6e6856 --- /dev/null +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_4XXXVF_HW_DATA_H_ +#define ADF_4XXXVF_HW_DATA_H_ + +#define ADF_4XXXIOV_PMISC_BAR 1 +#define ADF_4XXXIOV_ACCELERATORS_MASK 0x1 +#define ADF_4XXXIOV_ACCELENGINES_MASK 0x1 +#define ADF_4XXXIOV_MAX_ACCELERATORS 1 +#define ADF_4XXXIOV_MAX_ACCELENGINES 1 +#define ADF_4XXXIOV_NUM_RINGS_PER_BANK 2 +#define ADF_4XXXIOV_RX_RINGS_OFFSET 1 +#define ADF_4XXXIOV_TX_RINGS_MASK 0x1 +#define ADF_4XXXIOV_ETR_BAR 0 +#define ADF_4XXXIOV_ETR_MAX_BANKS 4 + +#define ADF_4XXXIOV_VINTSOU_OFFSET 0x0 +#define ADF_4XXXIOV_VINTMSK_OFFSET 0x4 +#define ADF_4XXXIOV_VINTSOUPF2VM_OFFSET 0x1000 +#define ADF_4XXXIOV_VINTMSKPF2VM_OFFSET 0x1004 +#define ADF_4XXX_DEF_ASYM_MASK 0x1 + +/* Virtual function fuses */ +#define ADF_4XXXIOV_VFFUSECTL0_OFFSET (0x40) +#define ADF_4XXXIOV_VFFUSECTL1_OFFSET (0x44) +#define ADF_4XXXIOV_VFFUSECTL2_OFFSET (0x4C) +#define ADF_4XXXIOV_VFFUSECTL4_OFFSET (0x1C4) +#define ADF_4XXXIOV_VFFUSECTL5_OFFSET (0x1C8) + +void adf_init_hw_data_4xxxiov(struct adf_hw_device_data *hw_data); +void adf_clean_hw_data_4xxxiov(struct adf_hw_device_data *hw_data); +u32 adf_4xxxvf_get_hw_cap(struct adf_accel_dev *accel_dev); +#endif diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c new file mode 100644 index 000000000000..f325ff4d75a4 --- /dev/null +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c @@ -0,0 +1,282 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include +#include +#include +#include "adf_4xxxvf_hw_data.h" +#include "adf_gen4_hw_data.h" +#include "adf_fw_counters.h" +#include "adf_cfg_device.h" +#include +#include +#include +#include +#include + +static MALLOC_DEFINE(M_QAT_4XXXVF, "qat_4xxxvf", "qat_4xxxvf"); + +#define ADF_SYSTEM_DEVICE(device_id) \ + { \ + PCI_VENDOR_ID_INTEL, device_id \ + } + +static const struct pci_device_id adf_pci_tbl[] = + { ADF_SYSTEM_DEVICE(ADF_4XXXIOV_PCI_DEVICE_ID), + ADF_SYSTEM_DEVICE(ADF_401XXIOV_PCI_DEVICE_ID), + { + 0, + } }; + +static int +adf_probe(device_t dev) +{ + const struct pci_device_id *id; + + for (id = adf_pci_tbl; id->vendor != 0; id++) { + if (pci_get_vendor(dev) == id->vendor && + pci_get_device(dev) == id->device) { + device_set_desc(dev, + "Intel " ADF_4XXXVF_DEVICE_NAME + " QuickAssist"); + return BUS_PROBE_GENERIC; + } + } + return ENXIO; +} + +static void +adf_cleanup_accel(struct adf_accel_dev *accel_dev) +{ + struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev; + struct adf_accel_dev *pf; + int i; + + if (accel_dev->dma_tag) + bus_dma_tag_destroy(accel_dev->dma_tag); + + for (i = 0; i < ADF_PCI_MAX_BARS; i++) { + struct adf_bar *bar = &accel_pci_dev->pci_bars[i]; + + if (bar->virt_addr) + bus_free_resource(accel_pci_dev->pci_dev, + SYS_RES_MEMORY, + bar->virt_addr); + } + + /* + * As adf_clean_hw_data_4xxxiov() will update class index, before + * index is updated, vf must be remove from accel_table. + */ + pf = adf_devmgr_pci_to_accel_dev(pci_find_pf(accel_pci_dev->pci_dev)); + adf_devmgr_rm_dev(accel_dev, pf); + + if (accel_dev->hw_device) { + switch (pci_get_device(accel_pci_dev->pci_dev)) { + case ADF_4XXXIOV_PCI_DEVICE_ID: + case ADF_401XXIOV_PCI_DEVICE_ID: + adf_clean_hw_data_4xxxiov(accel_dev->hw_device); + break; + default: + break; + } + free(accel_dev->hw_device, M_QAT_4XXXVF); + accel_dev->hw_device = NULL; + } + adf_cfg_dev_remove(accel_dev); +} + +static int +adf_attach(device_t dev) +{ + struct adf_accel_dev *accel_dev; + struct adf_accel_dev *pf; + struct adf_accel_pci *accel_pci_dev; + struct adf_hw_device_data *hw_data; + unsigned int i, bar_nr; + int ret = 0; + int rid; + struct adf_cfg_device *cfg_dev = NULL; + + accel_dev = device_get_softc(dev); + accel_dev->is_vf = true; + pf = adf_devmgr_pci_to_accel_dev(pci_find_pf(dev)); + + INIT_LIST_HEAD(&accel_dev->crypto_list); + accel_pci_dev = &accel_dev->accel_pci_dev; + accel_pci_dev->pci_dev = dev; + + if (bus_get_domain(dev, &accel_pci_dev->node) != 0) + accel_pci_dev->node = 0; + + /* Add accel device to accel table */ + if (adf_devmgr_add_dev(accel_dev, pf)) { + device_printf(GET_DEV(accel_dev), + "Failed to add new accelerator device.\n"); + return -EFAULT; + } + /* Allocate and configure device configuration structure */ + hw_data = malloc(sizeof(*hw_data), M_QAT_4XXXVF, M_WAITOK | M_ZERO); + if (!hw_data) { + ret = -ENOMEM; + goto out_err; + } + + accel_dev->hw_device = hw_data; + adf_init_hw_data_4xxxiov(accel_dev->hw_device); + accel_pci_dev->revid = pci_get_revid(dev); + + hw_data->fuses = pci_read_config(dev, ADF_4XXXIOV_VFFUSECTL4_OFFSET, 4); + + /* Get Accelerators and Accelerators Engines masks */ + hw_data->accel_mask = hw_data->get_accel_mask(accel_dev); + hw_data->ae_mask = hw_data->get_ae_mask(accel_dev); + hw_data->admin_ae_mask = hw_data->ae_mask; + accel_pci_dev->sku = hw_data->get_sku(hw_data); + + /* Create device configuration table */ + ret = adf_cfg_dev_add(accel_dev); + if (ret) + goto out_err; + + pci_set_max_read_req(dev, 1024); + + ret = bus_dma_tag_create(bus_get_dma_tag(dev), + 1, + 0, + BUS_SPACE_MAXADDR, + BUS_SPACE_MAXADDR, + NULL, + NULL, + BUS_SPACE_MAXSIZE, + /* BUS_SPACE_UNRESTRICTED */ 1, + BUS_SPACE_MAXSIZE, + 0, + NULL, + NULL, + &accel_dev->dma_tag); + + hw_data->accel_capabilities_mask = adf_4xxxvf_get_hw_cap(accel_dev); + + /* Find and map all the device's BARS */ + i = 0; + for (bar_nr = 0; i < ADF_PCI_MAX_BARS && bar_nr < PCIR_MAX_BAR_0; + bar_nr++) { + struct adf_bar *bar; + + rid = PCIR_BAR(bar_nr); + if (bus_get_resource(dev, SYS_RES_MEMORY, rid, NULL, NULL) != + 0) { + continue; + } + bar = &accel_pci_dev->pci_bars[i++]; + bar->virt_addr = bus_alloc_resource_any(dev, + SYS_RES_MEMORY, + &rid, + RF_ACTIVE); + if (!bar->virt_addr) { + device_printf(GET_DEV(accel_dev), + "Failed to map BAR %d\n", + bar_nr); + ret = ENXIO; + goto out_err; + } + bar->base_addr = rman_get_start(bar->virt_addr); + bar->size = rman_get_size(bar->virt_addr); + } + + if (i == 0) { + device_printf( + GET_DEV(accel_dev), + "No BARs mapped. Please check if PCI BARs are mapped correctly for device\n"); + ret = ENXIO; + goto out_err; + } + + pci_enable_busmaster(dev); + + /* Completion for VF2PF request/response message exchange */ + init_completion(&accel_dev->u1.vf.msg_received); + mutex_init(&accel_dev->u1.vf.rpreset_lock); + + ret = hw_data->config_device(accel_dev); + if (ret) + goto out_err; + + ret = adf_dev_init(accel_dev); + if (!ret) + ret = adf_dev_start(accel_dev); + + if (ret) { + device_printf( + GET_DEV(accel_dev), + "Failed to start - make sure PF enabled services match VF configuration.\n"); + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); + return 0; + } + + cfg_dev = accel_dev->cfg->dev; + adf_cfg_device_clear(cfg_dev, accel_dev); + free(cfg_dev, M_QAT); + accel_dev->cfg->dev = NULL; + + return ret; + +out_err: + adf_cleanup_accel(accel_dev); + return ret; +} + +static int +adf_detach(device_t dev) +{ + struct adf_accel_dev *accel_dev = device_get_softc(dev); + + if (!accel_dev) { + printf("QAT: Driver removal failed\n"); + return EFAULT; + } + + adf_flush_vf_wq(accel_dev); + clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); + adf_cleanup_accel(accel_dev); + return 0; +} + +static int +adf_modevent(module_t mod, int type, void *data) +{ + + switch (type) { + case MOD_UNLOAD: + adf_clean_vf_map(true); + return 0; + default: + return EOPNOTSUPP; + } +} + +static device_method_t adf_methods[] = { DEVMETHOD(device_probe, adf_probe), + DEVMETHOD(device_attach, adf_attach), + DEVMETHOD(device_detach, adf_detach), + + DEVMETHOD_END }; + +static driver_t adf_driver = { "qat", + adf_methods, + sizeof(struct adf_accel_dev) }; + +DRIVER_MODULE_ORDERED(qat_4xxxvf, + pci, + adf_driver, + adf_modevent, + NULL, + SI_ORDER_THIRD); +MODULE_VERSION(qat_4xxxvf, 1); +MODULE_DEPEND(qat_4xxxvf, qat_common, 1, 1, 1); +MODULE_DEPEND(qat_4xxxvf, qat_api, 1, 1, 1); +MODULE_DEPEND(qat_4xxxvf, linuxkpi, 1, 1, 1); diff --git a/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c index a13683800c8e..5a2a8575ab3e 100644 --- a/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_c3xxx_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -142,18 +143,6 @@ adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev, *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C3XXX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C3XXX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -362,8 +351,6 @@ adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -382,11 +369,8 @@ adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->measure_clock = measure_clock; hw_data->get_ae_clock = get_ae_clock; hw_data->reset_device = adf_reset_flr; @@ -410,6 +394,7 @@ adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c index 28dafa68a357..13fc41cb3454 100644 --- a/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c @@ -5,11 +5,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #include "adf_c4xxx_hw_data.h" #include "adf_c4xxx_reset.h" #include "adf_c4xxx_inline.h" @@ -608,18 +609,6 @@ adf_enable_mmp_error_correction(struct resource *csr, } } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C4XXX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C4XXX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -2154,8 +2143,6 @@ adf_init_hw_data_c4xxx(struct adf_hw_device_data *hw_data) hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -2180,11 +2167,8 @@ adf_init_hw_data_c4xxx(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = c4xxx_set_ssm_wdtimer; hw_data->check_slice_hang = c4xxx_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->reset_device = adf_reset_flr; hw_data->restore_device = adf_c4xxx_dev_restore; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->init_accel_units = adf_init_accel_units; hw_data->reset_hw_units = adf_c4xxx_reset_hw_units; hw_data->exit_accel_units = adf_exit_accel_units; @@ -2210,6 +2194,7 @@ adf_init_hw_data_c4xxx(struct adf_hw_device_data *hw_data) hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); hw_data->csr_info.arb_enable_mask = 0xF; } diff --git a/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c b/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c index bf73b60adc39..cfddc71dd371 100644 --- a/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_c62x_hw_data.h" #include "icp_qat_hw.h" #include "adf_cfg.h" @@ -146,18 +147,6 @@ adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev, *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C62X_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C62X_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -367,8 +356,6 @@ adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -387,11 +374,8 @@ adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->get_objs_num = get_objs_num; hw_data->get_obj_name = get_obj_name; hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask; @@ -415,6 +399,7 @@ adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c b/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c index 59c53db3947a..419de4f98bef 100644 --- a/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -4,10 +4,11 @@ #include "qat_freebsd.h" #include "adf_cfg.h" #include -#include +#include #include #include #include +#include #include "adf_dh895xcc_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -159,18 +160,6 @@ adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev, } } -static uint32_t -get_pf2vf_offset(uint32_t i) -{ - return ADF_DH895XCC_PF2VF_OFFSET(i); -} - -static uint32_t -get_vintmsk_offset(uint32_t i) -{ - return ADF_DH895XCC_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -354,8 +343,6 @@ adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -373,11 +360,8 @@ adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->exit_arb = adf_exit_arb; hw_data->get_arb_mapping = adf_get_arbiter_mapping; hw_data->enable_ints = adf_enable_ints; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->reset_device = adf_reset_sbr; hw_data->restore_device = adf_dev_restore; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->get_accel_cap = dh895xcc_get_hw_cap; hw_data->get_heartbeat_status = adf_get_heartbeat_status; hw_data->get_ae_clock = get_ae_clock; @@ -400,6 +384,7 @@ adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/modules/qat/qat_api/Makefile b/sys/modules/qat/qat_api/Makefile index 70886968ab56..810c67afdf6d 100644 --- a/sys/modules/qat/qat_api/Makefile +++ b/sys/modules/qat/qat_api/Makefile @@ -13,6 +13,9 @@ SRCS+= common/compression/dc_stats.c SRCS+= common/compression/dc_buffers.c SRCS+= common/compression/dc_dp.c SRCS+= common/compression/icp_sal_dc_err.c +SRCS+= common/compression/dc_chain.c +SRCS+= common/compression/dc_ns_datapath.c +SRCS+= common/compression/dc_ns_header_footer.c SRCS+= common/utils/lac_buffer_desc.c SRCS+= common/utils/lac_mem.c SRCS+= common/utils/lac_mem_pools.c @@ -27,6 +30,7 @@ SRCS+= common/ctrl/sal_compression.c SRCS+= common/ctrl/sal_ctrl_services.c SRCS+= common/ctrl/sal_create_services.c SRCS+= common/ctrl/sal_crypto.c +SRCS+= common/ctrl/sal_get_instances.c SRCS+= common/qat_comms/sal_qat_cmn_msg.c SRCS+= common/crypto/sym/lac_sym_api.c SRCS+= common/crypto/sym/lac_sym_cb.c diff --git a/sys/modules/qat/qat_common/Makefile b/sys/modules/qat/qat_common/Makefile index 22ea235fdce6..e37ab2ddf006 100644 --- a/sys/modules/qat/qat_common/Makefile +++ b/sys/modules/qat/qat_common/Makefile @@ -7,18 +7,20 @@ KMOD= qat_common SRCS+= adf_accel_engine.c adf_freebsd_admin.c adf_aer.c adf_cfg.c qat_common_module.c SRCS+= adf_heartbeat.c adf_freebsd_heartbeat_dbg.c -SRCS+= adf_dev_mgr.c adf_hw_arbiter.c +SRCS+= adf_freebsd_dev_processes.c adf_freebsd_uio.c adf_freebsd_uio_cleanup.c +SRCS+= adf_ctl_drv.c adf_dev_mgr.c adf_hw_arbiter.c SRCS+= adf_init.c adf_transport.c adf_isr.c adf_fw_counters.c adf_dev_err.c SRCS+= adf_gen2_hw_data.c SRCS+= adf_gen4_hw_data.c SRCS+= qat_freebsd.c SRCS+= adf_freebsd_cfg_dev_dbg.c adf_freebsd_ver_dbg.c -SRCS+= adf_cfg_device.c adf_cfg_section.c adf_cfg_instance.c adf_cfg_bundle.c +SRCS+= adf_cfg_device.c adf_cfg_section.c adf_cfg_instance.c adf_cfg_bundle.c adf_cfg_sysctl.c SRCS+= qat_hal.c qat_uclo.c -SRCS+= adf_vf_isr.c adf_pf2vf_msg.c -SRCS+= adf_vf2pf_msg.c -SRCS+= adf_pf2vf_capabilities.c -SRCS+= adf_pf2vf_ring_to_svc_map.c +SRCS+= adf_vf_isr.c +SRCS+= adf_gen4_pfvf.c +SRCS+= adf_gen4_timer.c +SRCS+= adf_pfvf_utils.c adf_pfvf_vf_msg.c adf_pfvf_vf_proto.c +SRCS+= adf_gen4vf_hw_csr_data.c SRCS+= adf_freebsd_transport_debug.c adf_clock.c SRCS+= adf_freebsd_cnvnr_ctrs_dbg.c SRCS+= adf_freebsd_pfvf_ctrs_dbg.c diff --git a/sys/modules/qat/qat_hw/Makefile b/sys/modules/qat/qat_hw/Makefile index 40c1d26b4687..8816a4bee83d 100644 --- a/sys/modules/qat/qat_hw/Makefile +++ b/sys/modules/qat/qat_hw/Makefile @@ -7,6 +7,7 @@ KMOD= qat_hw SRCS+= qat_c62x/adf_c62x_hw_data.c qat_c62x/adf_drv.c SRCS+= qat_200xx/adf_200xx_hw_data.c qat_200xx/adf_drv.c SRCS+= qat_4xxx/adf_4xxx_hw_data.c qat_4xxx/adf_drv.c +SRCS+= qat_4xxxvf/adf_4xxxvf_hw_data.c qat_4xxxvf/adf_drv.c SRCS+= qat_c3xxx/adf_c3xxx_hw_data.c qat_c3xxx/adf_drv.c SRCS+= qat_dh895xcc/adf_dh895xcc_hw_data.c qat_dh895xcc/adf_drv.c SRCS+= qat_c4xxx/adf_c4xxx_hw_data.c qat_c4xxx/adf_drv.c qat_c4xxx/adf_c4xxx_ae_config.c qat_c4xxx/adf_c4xxx_misc_error_stats.c