[][openwrt][mt7988][crypto][EIP197 DDK Porting]

[Description]
Add eip197 DDK(Driver Development Kit) and firmware
to eip197 package(crypto-eip)

eip197 DDK v5.6.1
eip197b-iew firmware v3.5

[Release-log]
N/A

Change-Id: I662327ecfbdac69742bf0b50362d7c28fc06372b
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7895272
diff --git a/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ifpp.bin b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ifpp.bin
new file mode 100644
index 0000000..1e5f2f8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ifpp.bin
Binary files differ
diff --git a/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ipue.bin b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ipue.bin
new file mode 100644
index 0000000..df12e73
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ipue.bin
Binary files differ
diff --git a/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ofpp.bin b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ofpp.bin
new file mode 100644
index 0000000..ae5509c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_ofpp.bin
Binary files differ
diff --git a/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_opue.bin b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_opue.bin
new file mode 100644
index 0000000..8ef1b23
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/firmware/bin/firmware_eip207_opue.bin
Binary files differ
diff --git a/package-21.02/kernel/crypto-eip/firmware/fwinfo.txt b/package-21.02/kernel/crypto-eip/firmware/fwinfo.txt
new file mode 100644
index 0000000..abbc77a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/firmware/fwinfo.txt
@@ -0,0 +1,5 @@
+FW-config:      FIRMWARE-GENERIC
+FW-version:     3.5
+HW-module:      eip197
+HW-config:      EIP-197b-iew-pp-1-axi-8r
+HW-min-version: 3.3
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/COPYING b/package-21.02/kernel/crypto-eip/src/ddk/COPYING
new file mode 100644
index 0000000..067e887
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/COPYING
@@ -0,0 +1,128 @@
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991 
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. 
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. 
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. 
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. 
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. 
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. 
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. 
+
+The precise terms and conditions for copying, distribution and modification follow. 
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". 
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 
+
+ 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. 
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 
+
+ 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: 
+a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) 
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. 
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. 
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 
+
+ 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: 
+  a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) 
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. 
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 
+
+ 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 
+
+ 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 
+
+ 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 
+
+ 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. 
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. 
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. 
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 
+
+ 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 
+
+ 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. 
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 
+
+ 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. 
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. 
+
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. 
+one line to give the program's name and an idea of what it does.
+Copyright (C) yyyy  name of author
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+Also add information on how to contact you by electronic and paper mail. 
+
+If the program is interactive, make it output a short notice like this when it starts in an interactive mode: 
+Gnomovision version 69, Copyright (C) year name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'.  This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. 
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: 
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written 
+by James Hacker.
+
+signature of Ty Coon, 1 April 1989
+Ty Coon, President of Vice
+
+
+This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/Makefile b/package-21.02/kernel/crypto-eip/src/ddk/Makefile
new file mode 100644
index 0000000..775e942
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/Makefile
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2023 MediaTek Inc.
+
+obj-$(CONFIG_RAMBUS_DDK) += crypto-eip-ddk.o
+
+# slad
+crypto-eip-ddk-y += ./slad/adapter_dmabuf.o
+crypto-eip-ddk-y += ./slad/adapter_driver197_init.o
+crypto-eip-ddk-y += ./slad/adapter_global_cs_init.o
+crypto-eip-ddk-y += ./slad/adapter_global_drbg_init.o
+crypto-eip-ddk-y += ./slad/adapter_global_eip207.o
+crypto-eip-ddk-y += ./slad/adapter_global_eip74.o
+crypto-eip-ddk-y += ./slad/adapter_global_eip97.o
+crypto-eip-ddk-y += ./slad/adapter_global_init.o
+crypto-eip-ddk-y += ./slad/adapter_lock_internal.o
+crypto-eip-ddk-y += ./slad/adapter_pcl_generic.o
+crypto-eip-ddk-y += ./slad/adapter_pcl_dtl.o
+crypto-eip-ddk-y += ./slad/adapter_pec_dma.o
+crypto-eip-ddk-y += ./slad/adapter_pec_pktbuf.o
+crypto-eip-ddk-y += ./slad/adapter_ring_eip202.o
+crypto-eip-ddk-y += ./slad/adapter_sglist.o
+crypto-eip-ddk-y += ./slad/lkm/adapter_firmware.o
+crypto-eip-ddk-y += ./slad/lkm/adapter_interrupts.o
+crypto-eip-ddk-y += ./slad/lkm/adapter_lock.o
+crypto-eip-ddk-y += ./slad/lkm/adapter_sleep.o
+# reference FPGA_Zynq_ZC706
+crypto-eip-ddk-y += ./slad/adapter_init.o
+
+# device
+crypto-eip-ddk-y += ./device/dmares_gen.o
+crypto-eip-ddk-y += ./device/device_generic.o
+crypto-eip-ddk-y += ./device/lkm/dmares_lkm.o
+crypto-eip-ddk-y += ./device/lkm/of/device_lkm.o
+crypto-eip-ddk-y += ./device/lkm/of/lkm.o
+
+# sa builder
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder.o
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_basic.o
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_extended_basic.o
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_extended_ipsec.o
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_ipsec.o
+# crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_srtp.o
+crypto-eip-ddk-y += ./kit/builder/sa/sa_builder_ssltls.o
+
+# token builder
+crypto-eip-ddk-y += ./kit/builder/token/token_builder_context.o
+crypto-eip-ddk-y += ./kit/builder/token/token_builder_core.o
+
+# eip197
+crypto-eip-ddk-y += ./kit/eip197/eip201.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_cd_format.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_cdr_dscr.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_cdr_event.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_cdr_fsm.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_cdr_init.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_global_init.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_rd_format.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_rdr_dscr.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_rdr_event.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_rdr_fsm.o
+crypto-eip-ddk-y += ./kit/eip197/eip202_rdr_init.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_flow_dtl.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_flow_generic.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_flow_internal.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_flue.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_fluec.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_global_init.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_ice.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_oce.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_rc.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_rc_internal.o
+crypto-eip-ddk-y += ./kit/eip197/eip207_support.o
+crypto-eip-ddk-y += ./kit/eip197/eip74.o
+crypto-eip-ddk-y += ./kit/eip197/eip97_global_event.o
+crypto-eip-ddk-y += ./kit/eip197/eip97_global_fsm.o
+crypto-eip-ddk-y += ./kit/eip197/eip97_global_init.o
+crypto-eip-ddk-y += ./kit/eip197/eip97_global_prng.o
+
+# log
+crypto-eip-ddk-y += ./kit/log/log.o
+
+# list
+crypto-eip-ddk-y += ./kit/list/list.o
+
+# iotoken
+crypto-eip-ddk-y += ./kit/iotoken/iotoken.o
+
+# ring
+crypto-eip-ddk-y += ./kit/ring/ringhelper.o
+
+# log
+crypto-eip-ddk-y += ./kit/log/log.o
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/device/device_generic.c b/package-21.02/kernel/crypto-eip/src/ddk/device/device_generic.c
new file mode 100644
index 0000000..c264e54
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/device/device_generic.c
@@ -0,0 +1,539 @@
+/* device_generic.c
+ *
+ * This is the generic Driver Framework v4 Device API implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Driver Framework Device API
+#include "device_mgmt.h"            // API to implement
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"             // IDENTIFIER_NOT_USED, NULL
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                   // strlen, strcpy
+
+// Driver Framework Device Internal interface
+#include "device_internal.h"        // Device_Internal_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Default configuration
+#include "c_device_generic.h"
+
+// Logging API
+#include "log.h"
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*-----------------------------------------------------------------------------
+ * DeviceLib_Device_Exists
+ *
+ * Checks if a device with DeviceName_p is already present in the device list
+ *
+ */
+static bool
+DeviceLib_Device_Exists(
+        const char * DeviceName_p)
+{
+    unsigned int i = 0;
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+
+    if (DeviceName_p == NULL)
+        return false;
+
+    while(DevAdmin_pp[i])
+    {
+        if (strcmp(DevAdmin_pp[i]->DevName, DeviceName_p) == 0)
+            return true;
+        i++;
+    }
+
+    return false;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * device_mgmt API
+ *
+ * These functions support finding a device given its name.
+ * A handle is returned that is needed in the device_rw API
+ * to read or write the device
+ */
+
+/*-----------------------------------------------------------------------------
+ * Device_Initialize
+ */
+int
+Device_Initialize(
+        void * CustomInitData_p)
+{
+    unsigned int res;
+    unsigned int DevStatCount = Device_Internal_Static_Count_Get();
+    unsigned int DevCount = Device_Internal_Count_Get();
+    const Device_Admin_Static_t * DevStatAdmin_p =
+                            Device_Internal_Admin_Static_Get();
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                            Device_Internal_Admin_Global_Get();
+
+    if (DevGlobalAdmin_p->fInitialized)
+        return 0; // already initialized, success
+
+    if (DevStatCount > DevCount)
+    {
+        LOG_CRIT("%s: Invalid number of static devices (%d), max %d\n",
+                 __func__,
+                 (int)DevStatCount,
+                 DevCount);
+        return -1; // failed
+    }
+
+    // Copy static devices
+    for (res = 0; res < DevStatCount; res++)
+    {
+        if (DeviceLib_Device_Exists(DevStatAdmin_p[res].DevName))
+        {
+            LOG_CRIT("%s: failed, device (index %d) with name %s exists\n",
+                     __func__,
+                     res,
+                     DevStatAdmin_p[res].DevName);
+            goto error_exit;
+        }
+
+        // Allocate memory for device administration data
+        DevAdmin_pp[res] = Device_Internal_Alloc(sizeof(Device_Admin_t));
+        if (DevAdmin_pp[res] == NULL)
+        {
+            LOG_CRIT("%s: failed to allocate device (index %d, name %s)\n",
+                     __func__,
+                     res,
+                     DevStatAdmin_p[res].DevName);
+            goto error_exit;
+        }
+
+        // Allocate and copy device name
+        DevAdmin_pp[res]->DevName =
+                Device_Internal_Alloc((unsigned int)strlen(DevStatAdmin_p[res].DevName)+1);
+        if (DevAdmin_pp[res]->DevName == NULL)
+        {
+            LOG_CRIT("%s: failed to allocate device (index %d) name %s\n",
+                     __func__,
+                     res,
+                     DevStatAdmin_p[res].DevName);
+            goto error_exit;
+        }
+        strcpy(DevAdmin_pp[res]->DevName, DevStatAdmin_p[res].DevName);
+
+        // Copy the rest of device data
+        DevAdmin_pp[res]->DeviceNr = DevStatAdmin_p[res].DeviceNr;
+        DevAdmin_pp[res]->FirstOfs = DevStatAdmin_p[res].FirstOfs;
+        DevAdmin_pp[res]->LastOfs  = DevStatAdmin_p[res].LastOfs;
+        DevAdmin_pp[res]->Flags    = DevStatAdmin_p[res].Flags;
+
+#ifdef HWPAL_DEVICE_MAGIC
+        DevAdmin_pp[res]->Magic    = HWPAL_DEVICE_MAGIC;
+#endif
+        DevAdmin_pp[res]->DeviceId = res;
+    }
+
+    res = (unsigned int)Device_Internal_Initialize(CustomInitData_p);
+    if (res != 0)
+    {
+        LOG_CRIT("%s: failed, error %d\n", __func__, res);
+        goto error_exit;
+    }
+
+    DevGlobalAdmin_p->fInitialized = true;
+    return 0; // success
+
+error_exit:
+    // Free all allocated memory
+    for (res = 0; res < DevStatCount; res++)
+        if (DevAdmin_pp[res])
+        {
+            Device_Internal_Free(DevAdmin_pp[res]->DevName);
+            Device_Internal_Free(DevAdmin_pp[res]);
+            DevAdmin_pp[res] = NULL;
+        }
+
+    return -1; // failed
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_UnInitialize
+ */
+void
+Device_UnInitialize(void)
+{
+    unsigned int DevCount = Device_Internal_Count_Get();
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    LOG_INFO("%s: unregister driver\n", __func__);
+
+    if (DevGlobalAdmin_p->fInitialized)
+    {
+        unsigned int i;
+
+        Device_Internal_UnInitialize();
+
+        // Free all allocated memory
+        for (i = 0; i < DevCount; i++)
+            if (DevAdmin_pp[i])
+            {
+                Device_Internal_Free(DevAdmin_pp[i]->DevName);
+                Device_Internal_Free(DevAdmin_pp[i]);
+                DevAdmin_pp[i] = NULL;
+            }
+
+        DevGlobalAdmin_p->fInitialized = false;
+    }
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Find
+ */
+Device_Handle_t
+Device_Find(
+        const char * DeviceName_p)
+{
+    unsigned int i;
+
+    unsigned int DevCount = Device_Internal_Count_Get();
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return NULL;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (DeviceName_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid name\n", __func__);
+        return NULL; // not supported, thus not found
+    }
+#endif
+
+    // walk through the device list and compare the device name
+    for (i = 0; i < DevCount; i++)
+        if (DevAdmin_pp[i] &&
+            strcmp(DeviceName_p, DevAdmin_pp[i]->DevName) == 0)
+            return Device_Internal_Find(DeviceName_p, i);
+
+    LOG_CRIT("%s: failed to find device '%s'\n", __func__, DeviceName_p);
+
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_GetProperties
+ */
+int
+Device_GetProperties(
+        const unsigned int Index,
+        Device_Properties_t * const Props_p,
+        bool * const fValid_p)
+{
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return -1;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (Index >= Device_Internal_Count_Get())
+    {
+        LOG_CRIT("%s: failed, invalid index %d, max device count %d\n",
+                 __func__,
+                 Index,
+                 Device_Internal_Count_Get());
+        return -1;
+    }
+
+    if (Props_p == NULL || fValid_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid pointers for device index %d\n",
+                 __func__,
+                 Index);
+        return -1;
+    }
+#endif
+
+    if (!DevAdmin_pp[Index])
+    {
+        LOG_INFO("%s: device with index %d not present\n",
+                 __func__,
+                 Index);
+        *fValid_p = false;
+    }
+    else
+    {
+        Props_p->Name_p          = DevAdmin_pp[Index]->DevName;
+        Props_p->StartByteOffset = DevAdmin_pp[Index]->FirstOfs;
+        Props_p->LastByteOffset  = DevAdmin_pp[Index]->LastOfs;
+        Props_p->Flags           = (char)DevAdmin_pp[Index]->Flags;
+        *fValid_p = true;
+    }
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Add
+ */
+int
+Device_Add(
+        const unsigned int Index,
+        const Device_Properties_t * const Props_p)
+{
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return -1;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (Index >= Device_Internal_Count_Get())
+    {
+        LOG_CRIT("%s: failed, invalid index %d, max device count %d\n",
+                 __func__,
+                 Index,
+                 Device_Internal_Count_Get());
+        return -1;
+    }
+
+    if (Props_p == NULL || Props_p->Name_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid properties for device index %d\n",
+                 __func__,
+                 Index);
+        return -1;
+    }
+#endif
+
+    if (DevAdmin_pp[Index])
+    {
+        LOG_CRIT("%s: device with index %d already added\n",
+                 __func__,
+                 Index);
+        return -1;
+    }
+
+    if (DeviceLib_Device_Exists(Props_p->Name_p))
+    {
+        LOG_CRIT("%s: device with name %s already added\n",
+                 __func__,
+                 Props_p->Name_p);
+        return -1;
+    }
+
+    // Allocate memory for device administration data
+    DevAdmin_pp[Index] = Device_Internal_Alloc(sizeof(Device_Admin_t));
+    if (DevAdmin_pp[Index] == NULL)
+    {
+        LOG_CRIT("%s: failed to allocate device (index %d, name %s)\n",
+                 __func__,
+                 Index,
+                 Props_p->Name_p);
+        return -1;
+    }
+
+    // Allocate and copy device name
+    DevAdmin_pp[Index]->DevName =
+                    Device_Internal_Alloc((unsigned int)strlen(Props_p->Name_p)+1);
+    if (DevAdmin_pp[Index]->DevName == NULL)
+    {
+        LOG_CRIT("%s: failed to allocate device (index %d) name %s\n",
+                 __func__,
+                 Index,
+                 Props_p->Name_p);
+        Device_Internal_Free(DevAdmin_pp[Index]);
+        DevAdmin_pp[Index] = NULL;
+        return -1;
+    }
+    strcpy(DevAdmin_pp[Index]->DevName, Props_p->Name_p);
+
+    // Copy the rest
+    DevAdmin_pp[Index]->FirstOfs  = Props_p->StartByteOffset;
+    DevAdmin_pp[Index]->LastOfs   = Props_p->LastByteOffset;
+    DevAdmin_pp[Index]->Flags     = (unsigned int)Props_p->Flags;
+
+    // Set default values
+    DevAdmin_pp[Index]->DeviceNr  = 0;
+#ifdef HWPAL_DEVICE_MAGIC
+    DevAdmin_pp[Index]->Magic     = HWPAL_DEVICE_MAGIC;
+#endif
+
+    DevAdmin_pp[Index]->DeviceId  = Index;
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Remove
+ */
+int
+Device_Remove(
+        const unsigned int Index)
+{
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return -1;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (Index >= Device_Internal_Count_Get())
+    {
+        LOG_CRIT("%s: failed, invalid index %d, max device count %d\n",
+                 __func__,
+                 Index,
+                 Device_Internal_Count_Get());
+        return -1;
+    }
+#endif
+
+    if (!DevAdmin_pp[Index])
+    {
+        LOG_CRIT("%s: device with index %d already removed\n",
+                 __func__,
+                 Index);
+        return -1;
+    }
+    else
+    {
+        // Free device memory
+        Device_Internal_Free(DevAdmin_pp[Index]->DevName);
+        Device_Internal_Free(DevAdmin_pp[Index]);
+        DevAdmin_pp[Index] = NULL;
+    }
+
+    return 0; // success
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetName
+ */
+char *
+Device_GetName(
+        const unsigned int Index)
+{
+    Device_Admin_t ** DevAdmin_pp = Device_Internal_Admin_Get();
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return NULL;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (Index >= Device_Internal_Count_Get())
+    {
+        LOG_CRIT("%s: failed, invalid index %d, max device count %d\n",
+                 __func__,
+                 Index,
+                 Device_Internal_Count_Get());
+        return NULL;
+    }
+#endif
+
+    if (!DevAdmin_pp[Index])
+    {
+        LOG_CRIT("%s: device with index %d already removed\n",
+                 __func__,
+                 Index);
+        return NULL;
+    }
+
+    return DevAdmin_pp[Index]->DevName; // success
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetIndex
+ */
+int
+Device_GetIndex(
+        const Device_Handle_t Device)
+{
+    Device_Global_Admin_t * DevGlobalAdmin_p =
+                        Device_Internal_Admin_Global_Get();
+
+    if (!DevGlobalAdmin_p->fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return -1;
+    }
+
+    return Device_Internal_GetIndex(Device);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetCount
+ */
+unsigned int
+Device_GetCount(void)
+{
+    return Device_Internal_Count_Get();
+}
+
+
+/* end of file device_generic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/device/dmares_gen.c b/package-21.02/kernel/crypto-eip/src/ddk/device/dmares_gen.c
new file mode 100644
index 0000000..6fedd9f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/device/dmares_gen.c
@@ -0,0 +1,1689 @@
+/* dmares_gen.c
+ *
+ * This Module implements the Generic DMA Resource API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "dmares_mgmt.h"
+#include "dmares_buf.h"
+#include "dmares_addr.h"
+#include "dmares_rw.h"
+
+// helper functions, not part of the actual DMAResource API
+#include "dmares_gen.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_dmares_gen.h"
+
+#include "device_swap.h"        // Device_SwapEndian32
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t, NULL, inline, bool,
+                                // IDENTIFIER_NOT_USED
+
+// Driver Framework C Run-Time Library Abstraction API
+#include "clib.h"               // ZEROINIT()
+
+// Logging API
+#include "log.h"                // LOG_*
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+// List API
+#include "list.h"
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+// HW- and OS-specific abstraction API
+#include "dmares_hwpal.h"
+
+#ifdef HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+// Shared Device Access DMA Pool API
+#include "shdevxs_dmapool.h"
+#endif
+#endif // HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#define DMARES_MAX_SIZE     (1 * 1024 * 1024) // 1 MB
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+/*
+ * Static (fixed-size) DMA banks properties implemented here:
+ *
+ * - One static bank contains one DMA pool;
+ *
+ * - Static bank types:
+ *     1) HWPAL_DMARESOURCE_BANK_STATIC - dynamically allocated
+ *     2) HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR - allocated on a fixed
+ *        address configured in c_dmares_gen.h
+ *
+ * - One DMA Pool contains a fixed compile-time configurable number of blocks;
+ *
+ * - All blocks in one DMA pool have the same fixed compile-time configurable
+ *   size;
+ *
+ * - The DMA pools for all the configured static banks are allocated
+ *   in DMAResource_Init() and freed in DMAResource_Uninit();
+ *
+ * - DMA resources can be allocated in a static bank using DMAResource_Alloc()
+ *   and they must be freed using DMAResource_Release();
+ *
+ * - Only sub-sets of DMA resources allocated in a static bank can be
+ *   registered in that bank using DMAResource_CheckAndRegister();
+ *   If the DMAResource_CheckAndRegister() function is called for a static bank
+ *   then it must use allocator type 82 ('R') and the required memory block
+ *   must belong to an already allocated DMA resource in that bank;
+ *
+ * - The DMAResource_CheckAndRegister() function can be called for a static
+ *   bank also using allocator type 78 ('N') to register a DMA-unsafe buffer;
+ *   These DMA resources must be subsequently freed using the DMABuf_Release()
+ *   function;
+ *
+ * - An "all-pool" DMA resource of size (nr_of_blocks * block_size) can be
+ *   allocated in a static bank using DMAResource_Alloc() where nr_of_blocks
+ *   and block_size are compile-time configuration parameters
+ *   (see HWPAL_DMARESOURCE_BANKS in c_dmares_gen.h);
+ *   The DMAResource_CheckAndRegister() function can be used to register
+ *   sub-sets of this DMA resource; Only one such a all-pool DMA resource
+ *   can be allocated in one static bank and must be freed using
+ *   DMAResource_Release() function;
+ *
+ * - No other DMA resources can be allocated in a static bank where an all-pool
+ *   DMA resource is allocated.
+ */
+typedef struct
+{
+    // Bank ID corresponding to DMA pool
+    uint8_t Bank;
+
+    // Bank type, see HWPAL_DMARESOURCE_BANK_*
+    unsigned int BankType;
+
+    // True if bank must be shared between multiple concurrent applications
+    bool fAppsShared;
+
+    // True if bank must be allocated in cached memory.
+    // Note: implementation may still chose to allocate it
+    //       in the non-cached memory.
+    bool fCached;
+
+    // For static HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR bank types only,
+    // otherwise ignored.
+    // Note: by default physical addresses are used.
+    void * Addr; // bank address
+
+    // List ID for elements associated with free blocks (DMA resources)
+    // in DMA pool
+    unsigned int PoolListID;
+
+    // List ID for used dangling elements which are not associated with
+    // free blocks in DMA pool
+    unsigned int DanglingListID;
+
+    // Pointer to array of elements which can be present either
+    // in the Pool list or in the Dangling list
+    // (but not in both at the same time)
+    List_Element_t * ListElements;
+
+    // Number of blocks in DMA pool
+    unsigned int BlockCount;
+
+    // Block size (in bytes)
+    unsigned int BlockByteCount;
+
+    // DMA pool handle
+    DMAResource_Handle_t PoolHandle;
+
+    // Pointer to a list lock for concurrent access protection,
+    // used for both lists
+    void * Lock_p;
+
+    // When true no more DMA resource can be allocated in the bank's DMA Pool
+    bool fDMAPoolLocked;
+
+} HWPAL_DMAResource_Bank_t;
+
+#define HWPAL_DMARESOURCE_BANK_ADD(_bank, _type, _shared, _cached, _addr, _blocks, _bsize) \
+               {_bank, _type, _shared, _cached, (void*)(_addr), 0, 0, NULL, _blocks, _bsize, NULL, NULL, false}
+
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+static HWPAL_DMAResource_Bank_t HWPAL_DMA_Banks[] =
+{
+    HWPAL_DMARESOURCE_BANKS
+};
+
+// Number of DMA pools supported calculated on HWPAL_DMA_Banks defined
+// in c_dmares_lkm.h
+#define HWPAL_DMARESOURCE_BANK_COUNT \
+        (sizeof(HWPAL_DMA_Banks) / sizeof(HWPAL_DMAResource_Bank_t))
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+// except when x is zero,
+// (x & (-x)) returns a value where all bits of `x' have
+// been cleared except the right-most '1'
+#define IS_POWER_OF_TWO(_x) (((_x) & (0 - (_x))) == (_x))
+
+
+/*----------------------------------------------------------------------------
+ * Forward declarations
+ */
+
+static inline void write32_volatile(uint32_t b, volatile void *addr)
+{
+    *(volatile uint32_t *) addr = b;
+}
+
+static inline uint32_t read32_volatile(const volatile void *addr)
+{
+    return *(const volatile uint32_t *) addr;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_IsSaneInput
+ *
+ * Return true if the DMAResource defined by the given address pair
+ * and properties appears to be valid.
+ */
+/* static */ bool
+DMAResourceLib_IsSaneInput(
+        const DMAResource_AddrPair_t * AddrPair_p,
+        const char * const AllocatorRef_p,
+        const DMAResource_Properties_t * Props_p)
+{
+    unsigned int Alignment = (unsigned int)Props_p->Alignment;
+
+    if ((Alignment < 1) ||
+        (Alignment > HWPAL_DMAResource_MaxAlignment_Get()) ||
+        !IS_POWER_OF_TWO(Alignment))
+    {
+        LOG_CRIT(
+            "DMAResourceLib_IsSaneInput: "
+            "Bad alignment value: %d\n",
+            Alignment);
+        return false;
+    }
+
+    // we support up to 1 megabyte buffers
+    if(Props_p->Size == 0 ||
+       Props_p->Size >= DMARES_MAX_SIZE)
+    {
+        LOG_CRIT(
+            "DMAResourceLib_IsSaneInput: "
+            "Bad size value: %d\n",
+            Props_p->Size);
+        return false;
+    }
+
+    if (AddrPair_p != NULL)
+    {
+        uintptr_t Address = (unsigned int)(uintptr_t)AddrPair_p->Address_p;
+
+        // Reject NULL as address
+        if (Address == 0)
+        {
+            LOG_CRIT(
+                "DMAResourceLib_IsSaneInput: "
+                "Bad address: %p\n",
+                AddrPair_p->Address_p);
+            return false;
+        }
+
+        // If requested verify if address is consistent with alignment
+        // Skip address alignment check for non-DMA safe buffers
+        if (AllocatorRef_p != NULL && *AllocatorRef_p != 'N')
+        {
+            if ((Address & (Alignment-1)) != 0)
+            {
+                LOG_CRIT(
+                    "DMAResourceLib_IsSaneInput: "
+                    "Address (%p) alignment (0x%x bytes) check failed\n",
+                    AddrPair_p->Address_p,
+                    Alignment);
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_AlignForSize
+ */
+/* static */ unsigned int
+DMAResourceLib_AlignForSize(
+        const unsigned int ByteCount,
+        const unsigned int AlignTo)
+{
+    unsigned int AlignedByteCount = ByteCount;
+
+    // Check if alignment and padding for length alignment is required
+    if (AlignTo > 1 && ByteCount % AlignTo)
+        AlignedByteCount = ByteCount / AlignTo * AlignTo + AlignTo;
+
+    return AlignedByteCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_AlignForAddress
+ */
+/* static */ unsigned int
+DMAResourceLib_AlignForAddress(
+        const unsigned int ByteCount,
+        const unsigned int AlignTo)
+{
+    unsigned int AlignedByteCount = ByteCount;
+
+    // Check if alignment is required
+    if(AlignTo > 1)
+    {
+        // Speculative padding for address alignment
+        AlignedByteCount += AlignTo;
+    }
+
+    return AlignedByteCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_LookupDomain
+ *
+ * Lookup given domain in Rec_p->AddrPairs array.
+ */
+/* static */ DMAResource_AddrPair_t *
+DMAResourceLib_LookupDomain(
+        const DMAResource_Record_t * Rec_p,
+        const DMAResource_AddrDomain_t Domain)
+{
+    const DMAResource_AddrPair_t * res = Rec_p->AddrPairs;
+
+    while (res->Domain != Domain)
+    {
+        if (res->Domain == 0)
+        {
+            return NULL;
+        }
+
+        if (++res == Rec_p->AddrPairs + DMARES_ADDRPAIRS_CAPACITY)
+        {
+            return NULL;
+        }
+    }
+
+    {
+        // Return 'res' but drop the 'const' qualifier
+        DMAResource_AddrPair_t * rv = (DMAResource_AddrPair_t *)((uintptr_t)res);
+        return rv;
+    }
+}
+
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Bank_Get
+ */
+static HWPAL_DMAResource_Bank_t *
+DMAResourceLib_DMAPool_Bank_Get(
+        const uint8_t Bank)
+{
+    unsigned int i, BankCount = HWPAL_DMARESOURCE_BANK_COUNT;
+
+    // we only support pre-configured memory banks
+    for(i = 0; i < BankCount; i++)
+    {
+        if (HWPAL_DMA_Banks[i].Bank == Bank)
+            return &HWPAL_DMA_Banks[i];
+    }
+
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Lock
+ *
+ * Checks if no memory blocks have already been obtained from
+ * the DMA pool of the provided bank.
+ *
+ * Returns true and locks the bank when no dangling blocks are found.
+ * Returns false if the pool is locked or if dangling blocks are found.
+ */
+static inline bool
+DMAResourceLib_DMAPool_Lock(
+        HWPAL_DMAResource_Bank_t * const Bank_p)
+{
+    List_Status_t List_Rc;
+    unsigned long Flags = 0;
+    unsigned int ElementCount = 1;
+
+    // DMA pool lock flag access protected by the bank lock
+    HWPAL_DMAResource_Lock_Acquire(Bank_p->Lock_p, &Flags);
+
+    if (Bank_p->fDMAPoolLocked == false)
+    {
+        List_Rc = List_GetListElementCount(Bank_p->DanglingListID,
+                                           NULL,
+                                           &ElementCount);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+            LOG_CRIT("DMAResourceLib_DMAPool_IsAllocated: failed for list %d\n",
+                     Bank_p->DanglingListID);
+
+            return false;
+        }
+
+        if (ElementCount == 0)
+            Bank_p->fDMAPoolLocked = true;
+    }
+
+    HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+    if (ElementCount == 0)
+        return true;
+    else
+        return false;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Unlock
+ *
+ * Unlocks the DMA pool of the provided bank so that blocks
+ * can be obtained from it using DMAResourceLib_DMAPool_Get().
+ */
+static bool
+DMAResourceLib_DMAPool_Unlock(
+        HWPAL_DMAResource_Bank_t * const Bank_p)
+{
+    bool fSuccess = false;
+    unsigned long Flags = 0;
+
+    // DMA pool lock flag access protected by the bank lock
+    HWPAL_DMAResource_Lock_Acquire(Bank_p->Lock_p, &Flags);
+
+    if (Bank_p->fDMAPoolLocked)
+    {
+        Bank_p->fDMAPoolLocked = false;
+        fSuccess = true;
+    }
+
+    HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+    return fSuccess;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Free
+ */
+static void
+DMAResourceLib_DMAPool_Free(void)
+{
+    unsigned int i, BankCount = HWPAL_DMARESOURCE_BANK_COUNT;
+    bool fFreed = false;
+
+    LOG_INFO("%s: freeing %d DMA banks\n", __func__, BankCount);
+
+    // Free allocated DMA pools
+    for(i = 0; i < BankCount; i++)
+    {
+        if (HWPAL_DMA_Banks[i].BankType == HWPAL_DMARESOURCE_BANK_DYNAMIC)
+        {
+            LOG_INFO("%s: skipping dynamic bank %d\n",
+                     __func__,
+                     HWPAL_DMA_Banks[i].Bank);
+            continue;
+        }
+
+        if (HWPAL_DMA_Banks[i].PoolHandle != NULL)
+        {
+#ifdef HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+            if (HWPAL_DMA_Banks[i].fAppsShared)
+            {
+                DMAResource_Record_t * Rec_p;
+
+                LOG_INFO("%s: freeing app-shared DMA bank %d\n", __func__, i);
+
+                // free administration resources
+                Rec_p = DMAResource_Handle2RecordPtr(HWPAL_DMA_Banks[i].PoolHandle);
+                if (Rec_p != NULL)
+                    Rec_p->Magic = 0;
+
+                DMAResource_DestroyRecord(HWPAL_DMA_Banks[i].PoolHandle);
+            }
+            else
+#endif // HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+            {
+                HWPAL_DMAResource_Release(HWPAL_DMA_Banks[i].PoolHandle);
+            }
+
+            HWPAL_DMA_Banks[i].PoolHandle = NULL;
+            fFreed = true;
+        }
+
+        if (HWPAL_DMA_Banks[i].ListElements != NULL)
+        {
+            HWPAL_DMAResource_MemFree(HWPAL_DMA_Banks[i].ListElements);
+            HWPAL_DMA_Banks[i].ListElements = NULL;
+            fFreed = true;
+        }
+
+        if (HWPAL_DMA_Banks[i].Lock_p != NULL)
+        {
+            HWPAL_DMAResource_Lock_Free(HWPAL_DMA_Banks[i].Lock_p);
+            HWPAL_DMA_Banks[i].Lock_p = NULL;
+            fFreed = true;
+        }
+
+        if (fFreed)
+        {
+            LOG_INFO("%s: %d freed static bank %d at offset 0x%p (cached=%d), "
+                    "for %d blocks, %d bytes each)\n",
+                    __func__,
+                    i,
+                    HWPAL_DMA_Banks[i].Bank,
+                    HWPAL_DMA_Banks[i].Addr,
+                    HWPAL_DMA_Banks[i].fCached,
+                    HWPAL_DMA_Banks[i].BlockCount,
+                    HWPAL_DMA_Banks[i].BlockByteCount);;
+        }
+
+        List_Uninit(HWPAL_DMA_Banks[i].PoolListID, NULL);
+        List_Uninit(HWPAL_DMA_Banks[i].DanglingListID, NULL);
+    } // for
+
+#ifdef HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+    SHDevXS_DMAPool_Uninit();
+#endif // HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Alloc
+ *
+ * Allocate DMA pools for static banks
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+static int
+DMAResourceLib_DMAPool_Alloc(void)
+{
+    unsigned int i, ListID, BankCount;
+    DMAResource_Properties_t PoolProperties;
+    HWPAL_DMAResource_Properties_Ext_t PoolPropertiesExt;
+
+    ZEROINIT(PoolProperties);
+    ZEROINIT(PoolPropertiesExt);
+
+    ListID = 0;
+
+    PoolProperties.Alignment  = HWPAL_DMARESOURCE_DMA_ALIGNMENT_BYTE_COUNT;
+    PoolProperties.fCached    = true;
+
+    BankCount = HWPAL_DMARESOURCE_BANK_COUNT;
+
+    if (BankCount > HWPAL_DMARESOURCE_MAX_NOF_BANKS)
+    {
+       LOG_CRIT("%s: failed, maximum %d DMA banks supported\n",
+                __func__,
+                HWPAL_DMARESOURCE_MAX_NOF_BANKS);
+       return -1;
+    }
+
+    LOG_INFO("%s: allocating %d DMA banks\n", __func__, BankCount);
+
+    for(i = 0; i < BankCount; i++)
+    {
+        unsigned int j, AlignedBlockByteCount;
+        List_Element_t * p;
+        uint8_t * Byte_p;
+
+        // Only static banks require DMA pool allocation
+        if (HWPAL_DMA_Banks[i].BankType == HWPAL_DMARESOURCE_BANK_DYNAMIC)
+        {
+            LOG_INFO("%s: skipping dynamic bank %d\n",
+                     __func__,
+                     HWPAL_DMA_Banks[i].Bank);
+            continue;
+        }
+
+        // Only non-cached SFA DMA banks are supported at the moment
+        if (HWPAL_DMA_Banks[i].BankType ==
+                HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR &&
+            HWPAL_DMA_Banks[i].fCached)
+        {
+            LOG_CRIT("%s: failed for bank %d, "
+                     "cached SFA DMA banks not supported\n",
+                     __func__,
+                     HWPAL_DMA_Banks[i].Bank);
+            goto fail;
+        }
+
+        AlignedBlockByteCount = DMAResourceLib_AlignForSize(
+                                HWPAL_DMA_Banks[i].BlockByteCount,
+                                (unsigned int)PoolProperties.Alignment);
+                               /*HWPAL_DMAResource_DCache_Alignment_Get()*/
+
+        PoolProperties.Bank      = HWPAL_DMA_Banks[i].Bank;
+        PoolProperties.Size      = AlignedBlockByteCount *
+                                               HWPAL_DMA_Banks[i].BlockCount;
+        PoolProperties.fCached   = HWPAL_DMA_Banks[i].fCached;
+
+        // Will be used only for HWPAL_DMA_Banks[i].BankType ==
+        // HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR
+        PoolPropertiesExt.Addr      = HWPAL_DMA_Banks[i].Addr;
+        PoolPropertiesExt.BankType  = HWPAL_DMA_Banks[i].BankType;
+
+        // Allocate DMA pool
+#ifdef HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+        if (HWPAL_DMA_Banks[i].fAppsShared)
+        {
+            DMAResource_Record_t * Rec_p;
+            DMAResource_AddrPair_t * Pair_p;
+            SHDevXS_DMAPool_t DMAPool;
+
+            LOG_INFO("%s: allocating app-shared DMA bank %d\n", __func__, i);
+
+            ZEROINIT(DMAPool);
+
+            if (SHDevXS_DMAPool_Init(&DMAPool) != 0)
+                goto fail;
+
+            if (DMAPool.ByteCount < PoolProperties.Size)
+                goto fail;
+
+            PoolProperties.Size = DMAPool.ByteCount;
+            PoolProperties.fCached = DMAPool.fCached;
+
+            // allocate record -> Handle & Rec_p
+            HWPAL_DMA_Banks[i].PoolHandle = DMAResource_CreateRecord();
+            if (HWPAL_DMA_Banks[i].PoolHandle == NULL)
+                goto fail;
+
+            Rec_p = DMAResource_Handle2RecordPtr(HWPAL_DMA_Banks[i].PoolHandle);
+            if (Rec_p == NULL)
+                goto fail;
+
+            Rec_p->Magic = DMARES_RECORD_MAGIC;
+            Rec_p->Props = PoolProperties;
+            Rec_p->AllocatorRef = 'A'; // Internal allocator
+            Rec_p->BufferSize = DMAPool.ByteCount;
+
+            HWPAL_DMAResource_Record_Update(DMAPool.Handle, Rec_p);
+
+            Pair_p = Rec_p->AddrPairs;
+
+            Pair_p->Address_p = DMAPool.DMA_Addr.p;
+            Pair_p->Domain = DMARES_DOMAIN_BUS;
+
+            ++Pair_p;
+            Pair_p->Address_p = DMAPool.HostAddr.p;
+            Pair_p->Domain = DMARES_DOMAIN_HOST;
+
+            Byte_p = (uint8_t*)DMAPool.HostAddr.p;
+        }
+        else
+#endif // !HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+        {
+            DMAResource_AddrPair_t PoolAddrPair;
+
+            ZEROINIT(PoolAddrPair);
+
+            if (HWPAL_DMAResource_Alloc(PoolProperties,
+                                        PoolPropertiesExt,
+                                        &PoolAddrPair,
+                                        &HWPAL_DMA_Banks[i].PoolHandle) != 0)
+                goto fail;
+
+            Byte_p = (uint8_t*)PoolAddrPair.Address_p;
+        }
+
+        // Allocate an array of list elements
+        p = HWPAL_DMAResource_MemAlloc(sizeof(List_Element_t) *
+                                           HWPAL_DMA_Banks[i].BlockCount);
+        if (p == NULL)
+            goto fail;
+
+        HWPAL_DMA_Banks[i].fDMAPoolLocked = false;
+        HWPAL_DMA_Banks[i].ListElements   = p;
+        HWPAL_DMA_Banks[i].PoolListID     = ListID++;
+        HWPAL_DMA_Banks[i].DanglingListID = ListID++;
+
+        if (List_Init(HWPAL_DMA_Banks[i].PoolListID, NULL) != LIST_STATUS_OK ||
+            List_Init(HWPAL_DMA_Banks[i].DanglingListID, NULL) != LIST_STATUS_OK)
+            goto fail;
+
+        for(j = 0; j < HWPAL_DMA_Banks[i].BlockCount; j++)
+        {
+            p->DataObject_p = Byte_p + j * AlignedBlockByteCount;
+            if (List_AddToHead(HWPAL_DMA_Banks[i].PoolListID, NULL, p++) !=
+                    LIST_STATUS_OK)
+                goto fail;
+        }
+
+        // Allocate a pool lock
+        HWPAL_DMA_Banks[i].Lock_p = HWPAL_DMAResource_Lock_Alloc();
+        if (HWPAL_DMA_Banks[i].Lock_p == NULL)
+            goto fail;
+
+        LOG_INFO("%s: %d allocated static bank %d at offset 0x%p (cached=%d), "
+                 "for %d blocks, %d (aligned %d) bytes each), handle 0x%p\n",
+                 __func__,
+                 i,
+                 HWPAL_DMA_Banks[i].Bank,
+                 HWPAL_DMA_Banks[i].Addr,
+                 HWPAL_DMA_Banks[i].fCached,
+                 HWPAL_DMA_Banks[i].BlockCount,
+                 HWPAL_DMA_Banks[i].BlockByteCount,
+                 AlignedBlockByteCount,
+                 HWPAL_DMA_Banks[i].PoolHandle);
+    } // for
+
+    return 0;
+
+fail:
+    DMAResourceLib_DMAPool_Free();
+
+    return -1;
+} // DMA pools allocation for static banks done
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Put
+ *
+ * Put a DMA resource host address to a DMA pool
+
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+static int
+DMAResourceLib_DMAPool_Put(
+        HWPAL_DMAResource_Bank_t * Bank_p,
+        void * const Addr_p)
+{
+    List_Status_t List_rc1, List_rc2;
+    List_Element_t * LE_p;
+    unsigned long Flags = 0;
+
+    // Dangling list access protected by lock
+    HWPAL_DMAResource_Lock_Acquire(Bank_p->Lock_p, &Flags);
+
+    List_rc1 = List_RemoveFromTail(Bank_p->DanglingListID, NULL, &LE_p);
+
+    LE_p->DataObject_p = Addr_p;
+
+    List_rc2 = List_AddToHead(Bank_p->PoolListID, NULL, LE_p);
+
+    HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+    if (List_rc1 != LIST_STATUS_OK || List_rc2 != LIST_STATUS_OK)
+    {
+        LOG_CRIT("DMAResourceLib_DMAPool_Put: failed\n");
+        return -1;
+    }
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_DMAPool_Get
+ *
+ * Get a DMA resource host address from a DMA pool
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+static int
+DMAResourceLib_DMAPool_Get(
+        HWPAL_DMAResource_Bank_t * Bank_p,
+        void ** const Addr_pp)
+{
+    List_Status_t List_rc1, List_rc2;
+    List_Element_t * LE_p;
+    unsigned long Flags = 0;
+
+    // Pool list access protected by lock
+    HWPAL_DMAResource_Lock_Acquire(Bank_p->Lock_p, &Flags);
+
+    if (Bank_p->fDMAPoolLocked)
+    {
+        HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+        LOG_CRIT("DMAResourceLib_DMAPool_Get: failed, DMA pool is locked\n");
+        return -1;
+    }
+
+    List_rc1 = List_RemoveFromTail(Bank_p->PoolListID, NULL, &LE_p);
+    if (List_rc1 != LIST_STATUS_OK)
+    {
+        HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+        LOG_CRIT("DMAResourceLib_DMAPool_Get: failed, out of list elements\n");
+        return -1;
+    }
+
+    List_rc2 = List_AddToHead(Bank_p->DanglingListID, NULL, LE_p);
+
+    HWPAL_DMAResource_Lock_Release(Bank_p->Lock_p, &Flags);
+
+    if (List_rc2 != LIST_STATUS_OK)
+    {
+        LOG_CRIT("DMAResourceLib_DMAPool_Get: "
+                 "failed to add to list of elements\n");
+        return -1;
+    }
+
+    *Addr_pp = LE_p->DataObject_p;
+
+    return 0;
+}
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Init
+ */
+bool
+DMAResource_Init(void)
+{
+    if (HWPAL_DMAResource_Init() == false)
+        return false;
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    if (DMAResourceLib_DMAPool_Alloc() == 0)
+        return true;
+    else
+    {
+        LOG_CRIT("%s: DMA pool allocation failed\n", __func__);
+        return false;
+    }
+#else
+    return true;
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_UnInit
+ *
+ * This function can be used to uninitialize the DMAResource administration.
+ * The caller must make sure that handles will not be used after this function
+ * returns.
+ * If memory was allocated by DMAResource_Init, this function will free it.
+ */
+void
+DMAResource_UnInit(void)
+{
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    DMAResourceLib_DMAPool_Free();
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+    HWPAL_DMAResource_UnInit();
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Alloc
+ */
+int
+DMAResource_Alloc(
+        const DMAResource_Properties_t RequestedProperties,
+        DMAResource_AddrPair_t * const AddrPair_p,
+        DMAResource_Handle_t * const Handle_p)
+{
+    HWPAL_DMAResource_Properties_Ext_t PoolPropertiesExt;
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    HWPAL_DMAResource_Bank_t * Bank_p;
+#endif
+
+    ZEROINIT(PoolPropertiesExt);
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    // Find the bank
+    Bank_p = DMAResourceLib_DMAPool_Bank_Get(RequestedProperties.Bank);
+    if (Bank_p == NULL)
+    {
+        LOG_CRIT("DMAResource_Alloc: failed for unsupported bank %d\n",
+                 (int)RequestedProperties.Bank);
+        return -1; // Bank not supported
+    }
+
+    if (Bank_p->BankType == HWPAL_DMARESOURCE_BANK_DYNAMIC)
+        // Handle non-static banks
+        return HWPAL_DMAResource_Alloc(RequestedProperties,
+                                       PoolPropertiesExt,
+                                       AddrPair_p,
+                                       Handle_p);
+    else
+    {   // Handle static banks
+
+        if (RequestedProperties.Size <= Bank_p->BlockByteCount)
+        {
+            int Rc;
+            DMAResource_AddrPair_t AddrPair;
+            DMAResource_Properties_t NewProperties;
+
+            if( DMAResourceLib_DMAPool_Get(Bank_p,
+                                           &AddrPair.Address_p) != 0)
+            {
+                LOG_WARN("DMAResource_Alloc: failed for static bank %d\n",
+                         (int)RequestedProperties.Bank);
+                return -1;
+            }
+
+            AddrPair.Domain = DMARES_DOMAIN_HOST;
+            // All memory blocks have the same fixed size in one bank
+            NewProperties = RequestedProperties;
+
+            if (NewProperties.Size != Bank_p->BlockByteCount)
+            {
+                LOG_INFO(
+                     "%s: changing requested resource size from %d to %d bytes "
+                     "for static bank %d\n",
+                     __func__,
+                     NewProperties.Size,
+                     Bank_p->BlockByteCount,
+                     (int)RequestedProperties.Bank);
+
+                NewProperties.Size = Bank_p->BlockByteCount;
+            }
+
+            if (NewProperties.fCached != Bank_p->fCached)
+            {
+                LOG_INFO(
+                     "%s: changing requested resource caching from %d to %d "
+                     "for static bank %d\n",
+                     __func__,
+                     NewProperties.fCached,
+                     Bank_p->fCached,
+                     (int)RequestedProperties.Bank);
+
+                NewProperties.fCached = Bank_p->fCached;
+            }
+
+            Rc = HWPAL_DMAResource_CheckAndRegister(NewProperties,
+                                                    AddrPair,
+                                                    'R',
+                                                    Handle_p);
+            if (Rc != 0)
+            {
+                // Failed to register the memory block obtained from
+                // the DMA pool as a DMA resource, put it back to the pool
+                DMAResourceLib_DMAPool_Put(Bank_p, AddrPair.Address_p);
+            }
+            else
+            {
+                AddrPair_p->Domain    = AddrPair.Domain;
+                AddrPair_p->Address_p = AddrPair.Address_p;
+            }
+
+            return Rc;
+        }
+        else if (RequestedProperties.Size ==
+                 Bank_p->BlockByteCount * Bank_p->BlockCount)
+        {   // Bank-full DMA resource allocation is requested
+
+            // Check that no DMA resources have been allocated in this bank yet
+            // If true then lock the bank so that
+            // no new DMA resources can be allocated in it
+            if(DMAResourceLib_DMAPool_Lock(Bank_p))
+            {
+                // No DMA resources have been allocated in this bank yet
+                *Handle_p = Bank_p->PoolHandle;
+
+                return 0; // Bank-full DMA resource is locked
+            }
+            else
+            {   // DMA resources have been already allocated in this bank
+                LOG_CRIT("DMAResource_Alloc: failed, "
+                         "all-pool DMA resource unavailable for bank %d\n",
+                         (int)RequestedProperties.Bank);
+                return -1;
+            }
+        }
+        else
+        {   // Requested size unsupported
+            LOG_CRIT("DMAResource_Alloc: failed, "
+                     "requested size %d > bank block size %d (bytes)\n",
+                     (int)RequestedProperties.Size,
+                     Bank_p->BlockByteCount);
+            return -1;
+        }
+    }
+#else
+    return HWPAL_DMAResource_Alloc(RequestedProperties,
+                                   PoolPropertiesExt,
+                                   AddrPair_p,
+                                   Handle_p);
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Release
+ */
+int
+DMAResource_Release(
+        const DMAResource_Handle_t Handle)
+{
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    HWPAL_DMAResource_Bank_t * Bank_p;
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_CRIT("DMAResource_Release: invalid handle %p\n", Handle);
+        return -1;
+    }
+
+    // Find the bank
+    Bank_p = DMAResourceLib_DMAPool_Bank_Get(Rec_p->Props.Bank);
+    if (Bank_p == NULL)
+    {
+        LOG_CRIT("DMAResource_Release: failed for unsupported bank %d\n",
+                 (int)Rec_p->Props.Bank);
+        return -1; // Bank not supported
+    }
+
+    // Handle non-static banks
+    if (Bank_p->BankType == HWPAL_DMARESOURCE_BANK_DYNAMIC)
+        return HWPAL_DMAResource_Release(Handle);
+    else
+    {
+        // Check if the all-pool DMA resource release is requested
+        if (Handle == Bank_p->PoolHandle)
+        {
+            // Unlock the DMA pool in the bank so that new DMA resources
+            // can be allocated in it
+            if (DMAResourceLib_DMAPool_Unlock(Bank_p) == false)
+            {
+                LOG_CRIT("DMAResource_Release: failed, "
+                         "all-pool DMA resource for bank %d "
+                         "already released\n",
+                         (int)Rec_p->Props.Bank);
+                return -1;
+            }
+            else
+                // DMA pool handle will be released by DMAResource_UnInit()
+                return 0; // Bank-full DMA resource is unlocked
+        }
+
+        if (Rec_p->AllocatorRef == 'R')
+        {
+            DMAResource_AddrPair_t * AddrPair_p;
+
+            AddrPair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+            if (AddrPair_p == NULL)
+            {
+                LOG_CRIT("DMAResource_Release: "
+                         "host address lookup failed for handle %p\n",
+                         Handle);
+                return -1;
+            }
+
+            // Check if resource belongs to a DMA pool
+            if (Bank_p->BlockByteCount == Rec_p->Props.Size)
+            {
+                // It does, put it back to pool
+                if (DMAResourceLib_DMAPool_Put(Bank_p,
+                                               AddrPair_p->Address_p) != 0)
+                {
+                    LOG_CRIT("DMAResource_Release: "
+                             "put to DMA pool failed for handle %p\n",
+                             Handle);
+                    return -1;
+                }
+            }
+        }
+
+        return HWPAL_DMAResource_Release(Handle);
+    }
+#else
+    return HWPAL_DMAResource_Release(Handle);
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_CheckAndRegister
+ */
+int
+DMAResource_CheckAndRegister(
+        const DMAResource_Properties_t RequestedProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        const char AllocatorRef,
+        DMAResource_Handle_t * const Handle_p)
+{
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+    HWPAL_DMAResource_Bank_t * Bank_p;
+
+    // Find the bank
+    Bank_p = DMAResourceLib_DMAPool_Bank_Get(RequestedProperties.Bank);
+    if (Bank_p == NULL)
+    {
+        LOG_CRIT(
+            "DMAResource_CheckAndRegister: failed for unsupported bank %d\n",
+            (int)RequestedProperties.Bank);
+
+        return -1; // Bank not supported
+    }
+
+    // Handle non-static banks
+    if (Bank_p->BankType == HWPAL_DMARESOURCE_BANK_DYNAMIC)
+        return HWPAL_DMAResource_CheckAndRegister(RequestedProperties,
+                                                  AddrPair,
+                                                  AllocatorRef,
+                                                  Handle_p);
+    else // Handle static banks in a different way
+    {
+        // Only allocators 'R' and 'N' are supported for static banks
+        if (AllocatorRef != 'R' && AllocatorRef != 'N')
+        {
+            LOG_CRIT(
+                "DMAResource_CheckAndRegister: failed, "
+                "allocator %c unsupported for static bank %d\n",
+                AllocatorRef,
+                (int)RequestedProperties.Bank);
+            return -1;
+        }
+
+        // Check if requested size is less than the bank memory block size
+        if ((AllocatorRef == 'R' &&
+             RequestedProperties.Size < Bank_p->BlockByteCount) ||
+             AllocatorRef == 'N')
+        {
+            return HWPAL_DMAResource_CheckAndRegister(RequestedProperties,
+                                                      AddrPair,
+                                                      AllocatorRef,
+                                                      Handle_p);
+        }
+        else
+        {
+            LOG_CRIT(
+                "DMAResource_CheckAndRegister: failed, "
+                "requested size %d >= block size %d in static bank %d\n",
+                RequestedProperties.Size,
+                Bank_p->BlockByteCount,
+                (int)RequestedProperties.Bank);
+            return -1;
+        }
+    }
+#else
+    return HWPAL_DMAResource_CheckAndRegister(RequestedProperties,
+                                              AddrPair,
+                                              AllocatorRef,
+                                              Handle_p);
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Read32
+ */
+uint32_t
+DMAResource_Read32(
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset)
+{
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+#ifndef HWPAL_DMARESOURCE_OPT1
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Read32: "
+            "Invalid handle %p\n",
+            Handle);
+
+        return 0;
+    }
+#endif
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if (WordOffset * 4 >= Rec_p->Props.Size)
+    {
+        LOG_WARN(
+            "DMAResource_Read32: "
+            "Invalid WordOffset %u for Handle %p\n",
+            WordOffset,
+            Handle);
+
+        return 0;
+    }
+#endif
+
+    Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+#ifndef HWPAL_DMARESOURCE_OPT1
+    if (Pair_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Read32: "
+            "No host address found for Handle %p?\n",
+            Handle);
+
+        return 0;
+    }
+#endif
+
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        uint32_t Value = read32_volatile(Address_p + WordOffset);
+
+#ifndef HWPAL_DMARESOURCE_OPT2
+        // swap endianness, if required
+        if (Rec_p->fSwapEndianness)
+            Value = Device_SwapEndian32(Value);
+#endif
+
+#ifdef HWPAL_TRACE_DMARESOURCE_READ
+        Log_FormattedMessage(
+            "DMAResource_Read32:  "
+            "(handle %p) "
+            "0x%08x = [%u] "
+            "(swap=%d)\n",
+            Handle,
+            Value,
+            WordOffset,
+            Rec_p->fSwapEndianness);
+#endif
+
+        return Value;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Write32
+ */
+void
+DMAResource_Write32(
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const uint32_t Value)
+{
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+#ifndef HWPAL_DMARESOURCE_OPT1
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Write32: "
+            "Invalid handle %p\n",
+            Handle);
+
+        return;
+    }
+#endif
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if (WordOffset * 4 >= Rec_p->Props.Size)
+    {
+        LOG_WARN(
+            "DMAResource_Write32: "
+            "Invalid WordOffset %u for Handle %p\n",
+            WordOffset,
+            Handle);
+
+        return;
+    }
+#endif
+
+    Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+#ifndef HWPAL_DMARESOURCE_OPT1
+    if (Pair_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Write32: "
+            "No host address found for Handle %p?\n",
+            Handle);
+
+        return;
+    }
+#endif
+
+#ifdef HWPAL_TRACE_DMARESOURCE_WRITE
+    Log_FormattedMessage(
+        "DMAResource_Write32: "
+        "(handle %p) "
+        "[%u] = 0x%08x "
+        "(swap=%d)\n",
+        Handle,
+        WordOffset,
+        Value,
+        Rec_p->fSwapEndianness);
+#endif
+
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        uint32_t WriteValue = Value;
+
+#ifndef HWPAL_DMARESOURCE_OPT2
+        // swap endianness, if required
+        if (Rec_p->fSwapEndianness)
+            WriteValue = Device_SwapEndian32(WriteValue);
+#endif
+
+        write32_volatile(WriteValue, Address_p + WordOffset);
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Read32Array
+ */
+void
+DMAResource_Read32Array(
+        const DMAResource_Handle_t Handle,
+        const unsigned int StartWordOffset,
+        const unsigned int WordCount,
+        uint32_t * Values_p)
+{
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+
+    if (WordCount == 0)
+        return;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Read32Array: "
+            "Invalid handle %p\n",
+            Handle);
+        return;
+    }
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if ((StartWordOffset + WordCount - 1) * 4 >= Rec_p->Props.Size)
+    {
+        LOG_WARN(
+            "DMAResource_Read32Array: "
+            "Invalid range: %u - %u\n",
+            StartWordOffset,
+            StartWordOffset + WordCount - 1);
+        return;
+    }
+#endif
+
+    Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+    if (Pair_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Read32Array: "
+            "No host address found for Handle %p?\n",
+            Handle);
+
+        return;
+    }
+
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        unsigned int i;
+
+        for (i = 0; i < WordCount; i++)
+        {
+            uint32_t Value = read32_volatile(Address_p + StartWordOffset + i);
+
+            // swap endianness, if required
+            if (Rec_p->fSwapEndianness)
+                Value = Device_SwapEndian32(Value);
+
+            Values_p[i] = Value;
+        } // for
+    }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_READ
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        if (Values_p == Address_p + StartWordOffset)
+        {
+            Log_FormattedMessage(
+                "DMAResource_Read32Array: "
+                "(handle %p) "
+                "[%u..%u] IN-PLACE "
+                "(swap=%d)\n",
+                Handle,
+                StartWordOffset,
+                StartWordOffset + WordCount - 1,
+                Rec_p->fSwapEndianness);
+        }
+        else
+        {
+            Log_FormattedMessage(
+                "DMAResource_Read32Array: "
+                "(handle %p) "
+                "[%u..%u] "
+                "(swap=%d)\n",
+                Handle,
+                StartWordOffset,
+                StartWordOffset + WordCount - 1,
+                Rec_p->fSwapEndianness);
+        }
+    }
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Write32Array
+ */
+void
+DMAResource_Write32Array(
+        const DMAResource_Handle_t Handle,
+        const unsigned int StartWordOffset,
+        const unsigned int WordCount,
+        const uint32_t * Values_p)
+{
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+
+    if (WordCount == 0)
+        return;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Write32Array: "
+            "Invalid handle %p\n",
+            Handle);
+        return;
+    }
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if ((StartWordOffset + WordCount - 1) * 4 >= Rec_p->Props.Size)
+    {
+        LOG_WARN(
+            "DMAResource_Write32Array: "
+            "Invalid range: %u - %u\n",
+            StartWordOffset,
+            StartWordOffset + WordCount - 1);
+        return;
+    }
+#endif
+
+    Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+    if (Pair_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Write32Array: "
+            "No host address found for Handle %p?\n",
+            Handle);
+
+        return;
+    }
+
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        unsigned int i;
+
+        for (i = 0; i < WordCount; i++)
+        {
+            uint32_t Value = Values_p[i];
+
+            // swap endianness, if required
+            if (Rec_p->fSwapEndianness)
+                Value = Device_SwapEndian32(Value);
+
+            write32_volatile(Value, Address_p + StartWordOffset + i);
+        } // for
+    }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_WRITE
+    {
+        uint32_t * Address_p = Pair_p->Address_p;
+        if (Values_p == Address_p + StartWordOffset)
+        {
+            Log_FormattedMessage(
+                "DMAResource_Write32Array: "
+                "(handle %p) "
+                "[%u..%u] IN-PLACE "
+                "(swap=%d)\n",
+                Handle,
+                StartWordOffset,
+                StartWordOffset + WordCount - 1,
+                Rec_p->fSwapEndianness);
+        }
+        else
+        {
+            Log_FormattedMessage(
+                "DMAResource_Write32Array: "
+                "(handle %p) "
+                "[%u..%u] "
+                "(swap=%d)\n",
+                Handle,
+                StartWordOffset,
+                StartWordOffset + WordCount - 1,
+                Rec_p->fSwapEndianness);
+        }
+    }
+#endif /* HWPAL_TRACE_DMARESOURCE_WRITE */
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_SwapEndianness_Set
+ */
+int
+DMAResource_SwapEndianness_Set(
+        const DMAResource_Handle_t Handle,
+        const bool fSwapEndianness)
+{
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_SwapEndianness_Set: "
+            "Invalid handle %p\n",
+            Handle);
+        return -1;
+    }
+
+    Rec_p->fSwapEndianness = fSwapEndianness;
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_SwapEndianness_Get
+ */
+int
+DMAResource_SwapEndianness_Get(
+        const DMAResource_Handle_t Handle)
+{
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_SwapEndianness_Get: "
+            "Invalid handle %p\n",
+            Handle);
+        return -1;
+    }
+
+    if (Rec_p->fSwapEndianness)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_AddPair
+ */
+int
+DMAResource_AddPair(
+        const DMAResource_Handle_t Handle,
+        const DMAResource_AddrPair_t Pair)
+{
+    DMAResource_Record_t * Rec_p;
+    DMAResource_AddrPair_t * AddrPair_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_AddPair: "
+            "Invalid handle %p\n",
+            Handle);
+        return -1;
+    }
+
+    // check if this pair already exists
+    AddrPair_p = DMAResourceLib_LookupDomain(Rec_p, Pair.Domain);
+    if (AddrPair_p)
+    {
+        LOG_INFO(
+            "DMAResource_AddPair: "
+            "Replacing address for handle %p?\n",
+            Handle);
+    }
+    else
+    {
+        // find a free slot to store this domain info
+        AddrPair_p = DMAResourceLib_LookupDomain(Rec_p, 0);
+        if (AddrPair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_AddPair: "
+                "Table overflow for handle %p\n",
+                Handle);
+            return -2;
+        }
+    }
+
+    if (!DMAResourceLib_IsSaneInput(&Pair, &Rec_p->AllocatorRef, &Rec_p->Props))
+    {
+        return -3;
+    }
+
+    *AddrPair_p = Pair;
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Translate
+ *
+ * This function implements a fake address translation which only extracts
+ * the required address information from the corresponding resource record
+ *
+ * All the address information is stored in the resource record in the
+ * DMAResource_Alloc() and DMAResource_CheckAndRegister() functions
+ *
+ */
+int
+DMAResource_Translate(
+        const DMAResource_Handle_t Handle,
+        const DMAResource_AddrDomain_t DestDomain,
+        DMAResource_AddrPair_t * const PairOut_p)
+{
+    DMAResource_Record_t * Rec_p;
+    DMAResource_AddrPair_t * Pair_p;
+
+    if (NULL == PairOut_p)
+    {
+        return -1;
+    }
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Translate: "
+            "Invalid handle %p\n",
+            Handle);
+        return -1;
+    }
+
+    switch (DestDomain)
+    {
+        case DMARES_DOMAIN_HOST_UNALIGNED:
+        case DMARES_DOMAIN_HOST:
+        case DMARES_DOMAIN_BUS:
+            Pair_p = DMAResourceLib_LookupDomain(Rec_p, DestDomain);
+            if (Pair_p != NULL)
+            {
+                *PairOut_p = *Pair_p;
+                return 0;
+            }
+            break;
+
+        default:
+            LOG_WARN(
+                "DMAResource_Translate: "
+                "Unsupported domain %u\n",
+                DestDomain);
+            PairOut_p->Address_p = NULL;
+            PairOut_p->Domain = DMARES_DOMAIN_UNKNOWN;
+            return -1;
+    } // switch
+
+    LOG_WARN(
+        "DMAResource_Translate: "
+        "No address for domain %u (Handle=%p)\n",
+        DestDomain,
+        Handle);
+
+    PairOut_p->Address_p = NULL;
+    PairOut_p->Domain = DMARES_DOMAIN_UNKNOWN;
+    return -1;
+}
+
+
+/* end of file dmares_gen.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/dmares_lkm.c b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/dmares_lkm.c
new file mode 100644
index 0000000..7fc041f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/dmares_lkm.c
@@ -0,0 +1,2214 @@
+/* dmares_lkm.c
+ *
+ * Linux Kernel-Mode implementation of the Driver Framework DMAResource API
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) some of the following interface(s):
+ */
+
+#include "dmares_mgmt.h"
+#include "dmares_buf.h"
+#include "dmares_rw.h"
+
+// Internal API implemented here
+#include "dmares_hwpal.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_dmares_lkm.h"
+
+#include "dmares_gen.h"         // Helpers from Generic DMAResource API
+
+#include "device_swap.h"        // Device_SwapEndian32
+#include "device_mgmt.h"        // Device_GetReference
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t, NULL, inline, bool,
+                                // IDENTIFIER_NOT_USED
+
+// Logging API
+#include "log.h"                // LOG_*
+
+// Linux Kernel API
+#include <linux/types.h>        // phys_addr_t
+#include <linux/slab.h>         // kmalloc, kfree
+#include <linux/dma-mapping.h>  // dma_sync_single_for_cpu, dma_alloc_coherent,
+                                // dma_free_coherent
+#include <linux/hardirq.h>      // in_atomic
+#include <linux/ioport.h>       // resource
+
+#ifdef HWPAL_LOCK_SLEEPABLE
+#include <linux/mutex.h>        // mutex_*
+#else
+#include <linux/spinlock.h>     // spinlock_*
+#endif
+#include <linux/version.h>
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#ifdef HWPAL_64BIT_HOST
+#ifdef HWPAL_DMARESOURCE_64BIT
+#define HWPAL_DMA_FLAGS 0 // No special requirements for address.
+#else
+#define HWPAL_DMA_FLAGS GFP_DMA // 64-bit host, 32-bit memory addresses
+#endif
+#else
+#define HWPAL_DMA_FLAGS 0 // No special requirements for address.
+#endif
+
+#define HWPAL_DMA_COHERENT_MAX_ATOMIC_SIZE 65536
+
+/*
+ Requirements on the records:
+  - pre-allocated array of records
+  - Total size of this array may not be limited by kmalloc size.
+  - valid between Create and Destroy
+  - re-use on a least-recently-used basis to make sure accidental continued
+    use after destroy does not cause crashes, allowing us to detect the
+    situation instead of crashing quickly.
+
+ Requirements on the handles:
+  - one handle per record
+  - valid between Create and Destroy
+  - quickly find the ptr-to-record belonging to the handle
+  - detect continued use of a handle after Destroy
+  - caller-hidden admin/status, thus not inside the record
+  - report leaking handles upon exit
+
+ Solution:
+  - handle cannot be a record number (no post-destroy use detection possible)
+  - Handle is a pointer into the Handles_p array. Each entry contains a record
+    index pair (or HWPAL_INVALID_INDEX if no record is associated with it).
+  - Array of records is divided into chunks, each chunk contains as many
+    records as fits into kmalloc buffer.
+  - Pointers to these chunks in RecordChunkPtrs_p array. Each record is
+    accessed via an index pair (chunk number and index within chunk).
+  - list of free locations in Handles_p:  FreeHandles
+  - list of free record index pairs     : FreeRecords
+ */
+
+typedef struct
+{
+    int ReadIndex;
+    int WriteIndex;
+    uint32_t * Nrs_p;
+} HWPAL_FreeList_t;
+
+typedef struct
+{
+    int CurIndex;
+} DMAResourceLib_InUseHandles_Iterator_t;
+
+
+/* Each chunk holds as many DMA resource records as will fit into a single
+   kmalloc buffer, but not more than 65536 as we use a 16-bit index  */
+#define MAX_RECORDS_PER_CHUNK \
+    (KMALLOC_MAX_SIZE / sizeof(DMAResource_Record_t) > 65536 ? 65536 : \
+     KMALLOC_MAX_SIZE / sizeof(DMAResource_Record_t))
+
+/* Each DMA handle stores a 32-bit index pair consisting of two 16-bit
+   fields to refer to the DMA resource record via RecordChunkPtrs_p.
+   RecordChunkPtrs_p is an array of pointers to contiguous arrays
+   (chunks) of DMA resource records.
+
+   Those 16-bit fields (chunk number and record index) are combined into a
+   single uint32_t
+   Special value HWPAL_INVALID_INDEX (0xffffffff) represents destroyed records.
+*/
+
+#define COMPOSE_RECNR(chunk, recidx) (((chunk) << 16) | recidx)
+#define CHUNK_OF(recnr) (((recnr) >> 16) & 0xffff)
+#define RECIDX_OF(recnr) ((recnr) & 0xffff)
+#define HWPAL_INVALID_INDEX 0xffffffff
+
+// Note: dma_get_cache_alignment() can be used in place of L1_CACHE_BYTES
+//       but it does not work on the 64-bit PowerPC Freescale P5020DS!
+#ifndef HWPAL_DMARESOURCE_DCACHE_LINE_SIZE
+#define HWPAL_DMARESOURCE_DCACHE_LINE_SIZE      L1_CACHE_BYTES
+#endif
+
+#ifdef HWPAL_DMARESOURCE_UNCACHED_MAPPING
+// arm and arm64 support this, powerpc does not
+#define IOREMAP_CACHE   ioremap_cache
+#else
+#define IOREMAP_CACHE   ioremap
+#endif // HWPAL_DMARESOURCE_UNCACHED_MAPPING
+
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+#define HWPAL_DMARESOURCE_SET_MASK        dma_set_coherent_mask
+#else
+#define HWPAL_DMARESOURCE_SET_MASK        dma_set_mask
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static int HandlesCount = 0; // remainder are valid only when this is != 0
+static int ChunksCount;
+
+static uint32_t * Handles_p;
+static DMAResource_Record_t ** RecordChunkPtrs_p;
+
+// array of pointers to arrays.
+static HWPAL_FreeList_t FreeHandles;
+static HWPAL_FreeList_t FreeRecords;
+
+static void * HWPAL_Lock_p;
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_IdxPair2RecordPtr
+ *
+ */
+static inline DMAResource_Record_t *
+DMAResourceLib_IdxPair2RecordPtr(uint32_t IdxPair)
+{
+    if (IdxPair != HWPAL_INVALID_INDEX &&
+        CHUNK_OF(IdxPair) < ChunksCount &&
+        RECIDX_OF(IdxPair) < MAX_RECORDS_PER_CHUNK &&
+        CHUNK_OF(IdxPair) * MAX_RECORDS_PER_CHUNK +
+        RECIDX_OF(IdxPair) < HandlesCount
+        )
+    {
+        return RecordChunkPtrs_p[CHUNK_OF(IdxPair)] + RECIDX_OF(IdxPair);;
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_FreeList_Get
+ *
+ * Gets the next entry from the freelist. Returns HWPAL_INVALID_INDEX
+ *  when the list is empty.
+ */
+static inline uint32_t
+DMAResourceLib_FreeList_Get(
+        HWPAL_FreeList_t * const List_p)
+{
+    uint32_t Nr = HWPAL_INVALID_INDEX;
+    int ReadIndex_Updated = List_p->ReadIndex + 1;
+
+    if (ReadIndex_Updated >= HandlesCount)
+        ReadIndex_Updated = 0;
+
+    // if post-increment ReadIndex == WriteIndex, the list is empty
+    if (ReadIndex_Updated != List_p->WriteIndex)
+    {
+        // grab the next number
+        Nr = List_p->Nrs_p[List_p->ReadIndex];
+        List_p->ReadIndex = ReadIndex_Updated;
+    }
+
+    return Nr;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_FreeList_Add
+ *
+ * Adds an entry to the freelist.
+ */
+static inline void
+DMAResourceLib_FreeList_Add(
+        HWPAL_FreeList_t * const List_p,
+        uint32_t Nr)
+{
+    if (List_p->WriteIndex == List_p->ReadIndex)
+    {
+        LOG_WARN(
+            "DMAResourceLib_FreeList_Add: "
+            "Attempt to add value %u to full list\n",
+            Nr);
+        return;
+    }
+
+    if (Nr == HWPAL_INVALID_INDEX)
+    {
+        LOG_WARN(
+            "DMAResourceLib_FreeList_Add: "
+            "Attempt to put invalid value: %u\n",
+            Nr);
+        return;
+    }
+
+    {
+        int WriteIndex_Updated = List_p->WriteIndex + 1;
+        if (WriteIndex_Updated >= HandlesCount)
+            WriteIndex_Updated = 0;
+
+        // store the number
+        List_p->Nrs_p[List_p->WriteIndex] = Nr;
+        List_p->WriteIndex = WriteIndex_Updated;
+    }
+}
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_InUseHandles_*
+ *
+ * Helper functions to iterate over all currently in-use handles.
+ *
+ * Usage:
+ *     DMAResourceLib_InUseHandles_Iterator_t it;
+ *     for (Handle = DMAResourceLib_InUseHandles_First(&it);
+ *          Handle != NULL;
+ *          Handle = DMAResourceLib_InUseHandles_Next(&it))
+ *     { ...
+ *
+ */
+static inline DMAResource_Record_t *
+DMAResourceLib_InUseHandles_Get(
+        DMAResourceLib_InUseHandles_Iterator_t * const it)
+{
+    DMAResource_Record_t * Rec_p;
+
+    do
+    {
+        if (it->CurIndex >= HandlesCount)
+            return NULL;
+
+        Rec_p = DMAResourceLib_IdxPair2RecordPtr(Handles_p[it->CurIndex++]);
+
+        if (Rec_p != NULL && Rec_p->Magic != DMARES_RECORD_MAGIC)
+            Rec_p = NULL;
+    }
+    while(Rec_p == NULL);
+
+    return Rec_p;
+}
+
+
+static inline DMAResource_Record_t *
+DMAResourceLib_InUseHandles_First(
+        DMAResourceLib_InUseHandles_Iterator_t * const it)
+{
+    it->CurIndex = 0;
+    return DMAResourceLib_InUseHandles_Get(it);
+}
+
+
+static inline DMAResource_Record_t *
+DMAResourceLib_InUseHandles_Next(
+        DMAResourceLib_InUseHandles_Iterator_t * const it)
+{
+    return DMAResourceLib_InUseHandles_Get(it);
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_IsSubRangeOf
+ *
+ * Return true if the address range defined by `AddrPair1' and `Size1' is
+ * within the address range defined by `AddrPair2' and `Size2'.
+ */
+static bool
+DMAResourceLib_IsSubRangeOf(
+        const DMAResource_AddrPair_t * const AddrPair1,
+        const unsigned int Size1,
+        const DMAResource_AddrPair_t * const AddrPair2,
+        const unsigned int Size2)
+{
+    if (AddrPair1->Domain == AddrPair2->Domain)
+    {
+        const uint8_t * Addr1 = AddrPair1->Address_p;
+        const uint8_t * Addr2 = AddrPair2->Address_p;
+
+        if ((Size1 <= Size2) &&
+            (Addr2 <= Addr1) &&
+            ((Addr1 + Size1) <= (Addr2 + Size2)))
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_Find_Matching_DMAResource
+ *
+ * Return a pointer to the DMAResource record for a currently allocated or
+ * attached DMA buffer that matches the given `Properties' and `AddrPair'.
+ * The match can be either exact or indicate that the buffer defined by
+ * `Properties and `AddrPair' is a proper sub section of the allocated or
+ * attached buffer.
+ */
+static DMAResource_Record_t *
+DMAResourceLib_Find_Matching_DMAResource(
+        const DMAResource_Properties_t * const Properties,
+        const DMAResource_AddrPair_t AddrPair)
+{
+    DMAResourceLib_InUseHandles_Iterator_t it;
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+    unsigned int Size;
+
+    for (Rec_p = DMAResourceLib_InUseHandles_First(&it);
+         Rec_p != NULL;
+         Rec_p = DMAResourceLib_InUseHandles_Next(&it))
+    {
+        if (Rec_p->AllocatorRef == 'R' || Rec_p->AllocatorRef == 'N')
+        {
+            // skip registered buffers when looking for a match,
+            // i.e. only consider allocated buffers.
+            continue;
+        }
+
+        if (Properties->Bank != Rec_p->Props.Bank  ||
+            Properties->Size > Rec_p->Props.Size ||
+            Properties->Alignment > Rec_p->Props.Alignment)
+        {
+            // obvious mismatch in properties
+            continue;
+        }
+
+        Size = Properties->Size;
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+        if (Pair_p != NULL &&
+            DMAResourceLib_IsSubRangeOf(&AddrPair, Size, Pair_p,
+                                            Rec_p->Props.Size))
+        {
+            return Rec_p;
+        }
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_BUS);
+        if (Pair_p != NULL &&
+            DMAResourceLib_IsSubRangeOf(&AddrPair, Size, Pair_p,
+                                            Rec_p->Props.Size))
+        {
+            return Rec_p;
+        }
+    } // for
+
+    return NULL;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_Setup_Record
+ *
+ * Setup most fields of a given DMAResource record, except for the
+ * AddrPairs array.
+ */
+static void
+DMAResourceLib_Setup_Record(
+        const DMAResource_Properties_t * const Props_p,
+        const char AllocatorRef,
+        DMAResource_Record_t * const Rec_p,
+        const unsigned int AllocatedSize)
+{
+    Rec_p->Props = *Props_p;
+    Rec_p->AllocatorRef = AllocatorRef;
+    Rec_p->BufferSize = AllocatedSize;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MaxAlignment_Get
+ */
+unsigned int
+HWPAL_DMAResource_MaxAlignment_Get(void)
+{
+    return (1 * 1024 * 1024); // 1 MB
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_DCache_Alignment_Get
+ */
+unsigned int
+HWPAL_DMAResource_DCache_Alignment_Get(void)
+{
+#ifdef HWPAL_ARCH_COHERENT
+    unsigned int AlignTo = 1; // No cache line alignment required
+#else
+    unsigned int AlignTo = HWPAL_DMARESOURCE_DCACHE_LINE_SIZE;
+#endif // HWPAL_ARCH_COHERENT
+
+#if defined(HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT) || \
+    defined (HWPAL_DRMARESOURCE_ALLOW_UNALIGNED_ADDRESS)
+    AlignTo = 1; // No cache line alignment required
+#endif
+
+    return AlignTo;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MemAlloc
+ */
+void *
+HWPAL_DMAResource_MemAlloc(
+        size_t ByteCount)
+{
+    gfp_t flags = 0;
+
+    if (in_atomic())
+        flags |= GFP_ATOMIC;    // non-sleepable
+    else
+        flags |= GFP_KERNEL;    // sleepable
+
+    return kmalloc(ByteCount, flags);
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MemFree
+ */
+void
+HWPAL_DMAResource_MemFree(
+        void * Buf_p)
+{
+    kfree (Buf_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Alloc
+ */
+void *
+HWPAL_DMAResource_Lock_Alloc(void)
+{
+#ifdef HWPAL_LOCK_SLEEPABLE
+    struct mutex * HWPAL_Lock = HWPAL_DMAResource_MemAlloc(sizeof(mutex));
+    if (HWPAL_Lock == NULL)
+        return NULL;
+
+    LOG_INFO("HWPAL_DMAResource_Lock_Alloc: Lock = mutex\n");
+    mutex_init(HWPAL_Lock);
+
+    return HWPAL_Lock;
+#else
+    spinlock_t * HWPAL_SpinLock;
+
+    size_t LockSize = sizeof(spinlock_t);
+    if (LockSize == 0)
+        LockSize = 4;
+
+    HWPAL_SpinLock = HWPAL_DMAResource_MemAlloc(LockSize);
+    if (HWPAL_SpinLock == NULL)
+        return NULL;
+
+    LOG_INFO("HWPAL_DMAResource_Lock_Alloc: Lock = spinlock\n");
+    spin_lock_init(HWPAL_SpinLock);
+
+    return HWPAL_SpinLock;
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Free
+ */
+void
+HWPAL_DMAResource_Lock_Free(void * Lock_p)
+{
+    HWPAL_DMAResource_MemFree(Lock_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Acquire
+ */
+void
+HWPAL_DMAResource_Lock_Acquire(
+        void * Lock_p,
+        unsigned long * Flags)
+{
+#ifdef HWPAL_LOCK_SLEEPABLE
+    IDENTIFIER_NOT_USED(Flags);
+    mutex_lock((struct mutex*)Lock_p);
+#else
+    spin_lock_irqsave((spinlock_t *)Lock_p, *Flags);
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Release
+ */
+void
+HWPAL_DMAResource_Lock_Release(
+        void * Lock_p,
+        unsigned long * Flags)
+{
+#ifdef HWPAL_LOCK_SLEEPABLE
+    IDENTIFIER_NOT_USED(Flags);
+    mutex_unlock((struct mutex*)Lock_p);
+#else
+    spin_unlock_irqrestore((spinlock_t *)Lock_p, *Flags);
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Alloc
+ */
+int
+HWPAL_DMAResource_Alloc(
+        const DMAResource_Properties_t RequestedProperties,
+        const HWPAL_DMAResource_Properties_Ext_t RequestedPropertiesExt,
+        DMAResource_AddrPair_t * const AddrPair_p,
+        DMAResource_Handle_t * const Handle_p)
+{
+    DMAResource_Properties_t ActualProperties;
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Handle_t Handle;
+    DMAResource_Record_t * Rec_p = NULL;
+
+    unsigned int AlignTo = RequestedProperties.Alignment;
+
+    ZEROINIT(ActualProperties);
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if ((NULL == AddrPair_p) || (NULL == Handle_p))
+        return -1;
+
+    if (!DMAResourceLib_IsSaneInput(NULL, NULL, &RequestedProperties))
+        return -1;
+#endif
+
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+    if (RequestedPropertiesExt.BankType ==
+            HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+    {
+        LOG_CRIT("DMAResource_Alloc: fixed address DMA banks not supported for"
+                 " cache-coherent allocations with "
+                 "HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT\n");
+        return -1;
+    }
+#endif // HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+    // Allocate record
+    Handle = DMAResource_CreateRecord();
+    if (NULL == Handle)
+        return -1;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (NULL == Rec_p)
+    {
+        DMAResource_DestroyRecord(Handle);
+        return -1;
+    }
+
+    ActualProperties.Bank       = RequestedProperties.Bank;
+
+#ifdef HWPAL_ARCH_COHERENT
+    ActualProperties.fCached    = false;
+#else
+    if (RequestedPropertiesExt.BankType ==
+                HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+        ActualProperties.fCached    = RequestedProperties.fCached;
+    else
+        // This implementation does not allocate to non-cached resources
+        ActualProperties.fCached    = true;
+#endif // HWPAL_ARCH_COHERENT
+
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+    ActualProperties.fCached    = false;
+#endif // HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+    if (ActualProperties.fCached != RequestedProperties.fCached)
+    {
+        LOG_INFO("%s: changing requested resource caching from %d to %d "
+                 "for bank %d\n",
+                 __func__,
+                 RequestedProperties.fCached,
+                 ActualProperties.fCached,
+                 RequestedProperties.Bank);
+    }
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+    if (ActualProperties.fCached &&
+        HWPAL_DMAResource_DCache_Alignment_Get() > AlignTo)
+    {
+        AlignTo = HWPAL_DMAResource_DCache_Alignment_Get();
+    }
+
+    ActualProperties.Alignment  = AlignTo;
+
+    // Hide the allocated size from the caller, since (s)he is not
+    // supposed to access/use any space beyond what was requested
+    ActualProperties.Size = RequestedProperties.Size;
+
+    Rec_p->BankType = RequestedPropertiesExt.BankType;
+
+    // Allocate DMA resource
+    {
+        struct device * DMADevice_p;
+        size_t n = 0;
+        void  * UnalignedAddr_p = NULL;
+        void * AlignedAddr_p = NULL;
+        dma_addr_t DMAAddr = 0;
+        phys_addr_t PhysAddr = 0;
+        Device_Data_t DevData;
+
+        ZEROINIT(DevData);
+
+        // Get device reference for this resource
+        DMADevice_p = Device_GetReference(NULL, &DevData);
+
+        // Step 1: Allocate a buffer
+        if (RequestedPropertiesExt.BankType ==
+                HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+        {
+            struct resource * Resource_p;
+            void __iomem * IOMem_p;
+
+            // Option 1: Fixed address buffer allocation
+
+            PhysAddr = (phys_addr_t)(uintptr_t)RequestedPropertiesExt.Addr +
+                                        (phys_addr_t)(uintptr_t)DevData.PhysAddr;
+
+            // Check bank address alignment
+            if (PhysAddr & (PAGE_SIZE-1))
+            {
+                DMAResource_DestroyRecord(Handle);
+                LOG_CRIT("DMAResource_Alloc: unaligned fixed address for "
+                         "bank %d, address 0x%p, page size %lu\n",
+                         RequestedProperties.Bank,
+                         (void *)(uintptr_t)PhysAddr,
+                         PAGE_SIZE);
+                return -1;
+            }
+
+            // Round size up to a multiple of PAGE_SIZE
+            n = (RequestedProperties.Size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+
+            Resource_p = request_mem_region(PhysAddr, n, "DMA-bank");
+            if (!Resource_p)
+            {
+                DMAResource_DestroyRecord(Handle);
+                LOG_CRIT("DMAResource_Alloc: request_mem_region() failed, "
+                        "resource addr 0x%p, size %d\n",
+                         (void *)(uintptr_t)PhysAddr,
+                         (unsigned int)n);
+                return -1;
+            }
+
+            if (RequestedProperties.fCached)
+                IOMem_p = IOREMAP_CACHE(PhysAddr, n);
+            else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
+                IOMem_p = ioremap_cache(PhysAddr, n);
+#else
+                IOMem_p = ioremap_nocache(PhysAddr, n);
+#endif
+            // Ignore __iomem address space
+            UnalignedAddr_p = (void *)(uintptr_t)IOMem_p;
+
+            if (!UnalignedAddr_p)
+            {
+                release_mem_region(PhysAddr, n);
+                DMAResource_DestroyRecord(Handle);
+                LOG_CRIT("DMAResource_Alloc: ioremap() failed, resource "
+                         "addr 0x%p, cached %d, size %d\n",
+                         (void *)(uintptr_t)PhysAddr,
+                         RequestedProperties.fCached,
+                         (unsigned int)n);
+                return -1;
+            }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Alloc: allocated static bank at "
+                     "phys addr 0x%p, offset 0x%p, size %d\n",
+                     (void*)PhysAddr,
+                     (void*)RequestedPropertiesExt.Addr,
+                     (unsigned int)n);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+            if (PAGE_SIZE > AlignTo)
+            {
+                // ioremap granularity is PAGE_SIZE
+                ActualProperties.Alignment  = AlignTo = PAGE_SIZE;
+            }
+        }
+        else
+        {
+            gfp_t flags = HWPAL_DMA_FLAGS;
+
+            // Option 2: Non-fixed dynamic address buffer allocation
+
+            // Align if required
+            n = DMAResourceLib_AlignForAddress(
+                 DMAResourceLib_AlignForSize(RequestedProperties.Size,
+                 AlignTo),
+                 AlignTo);
+
+            if (in_atomic())
+                flags |= GFP_ATOMIC;    // non-sleepable
+            else
+                flags |= GFP_KERNEL;    // sleepable
+
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+            if (n <= HWPAL_DMA_COHERENT_MAX_ATOMIC_SIZE)
+                flags = GFP_ATOMIC;
+            UnalignedAddr_p = dma_alloc_coherent(
+                                     DMADevice_p, n, &DMAAddr, flags);
+#else
+            UnalignedAddr_p = kmalloc(n, flags);
+#endif // HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+            if (UnalignedAddr_p == NULL)
+            {
+                LOG_CRIT("DMAResource_Alloc: failed for handle 0x%p,"
+                        " size %d\n",
+                         Handle,(unsigned int)n);
+                DMAResource_DestroyRecord(Handle);
+                return -1;
+            }
+        }
+
+        DMAResourceLib_Setup_Record(&ActualProperties, 'A', Rec_p, n);
+
+        // Step 2: Align the allocated buffer
+        {
+            unsigned long AlignmentOffset;
+            unsigned long UnalignedAddress = ((unsigned long)UnalignedAddr_p);
+
+            AlignmentOffset = UnalignedAddress % AlignTo;
+
+            // Check if address needs to be aligned
+            if( AlignmentOffset )
+                AlignedAddr_p =
+                        (void*)(UnalignedAddress + AlignTo - AlignmentOffset);
+            else
+                AlignedAddr_p = UnalignedAddr_p; // No alignment required
+        }
+
+        // Step 3: Get the DMA address of the allocated buffer
+        if (RequestedPropertiesExt.BankType ==
+                        HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+        {
+            DMAAddr = PhysAddr - (phys_addr_t)(uintptr_t)DevData.PhysAddr -
+                            HWPAL_DMARESOURCE_BANK_STATIC_OFFSET;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Alloc: Handle 0x%p, "
+                     "bus address requested/actual 0x%p/0x%p\n",
+                     Handle,
+                     RequestedPropertiesExt.Addr,
+                     (void*)DMAAddr);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+        }
+        else
+        {
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+            DMAAddr = virt_to_phys (AlignedAddr_p);
+#else
+
+#ifndef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+            DMAAddr = dma_map_single(DMADevice_p, AlignedAddr_p, n,
+                                     DMA_BIDIRECTIONAL);
+            if (dma_mapping_error(DMADevice_p, DMAAddr))
+            {
+                kfree(AlignedAddr_p);
+
+                DMAResource_DestroyRecord(Handle);
+
+                LOG_WARN(
+                        "DMAResource_Alloc: "
+                        "Failed to map DMA address for host address 0x%p, "
+                        "for handle 0x%p\n",
+                        AlignedAddr_p,
+                        Handle);
+
+                return -1;
+            }
+#endif // !HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+            if (DMAAddr == 0)
+            {
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+                dma_free_coherent(DMADevice_p, n, UnalignedAddr_p, DMAAddr);
+#else
+                kfree(UnalignedAddr_p);
+#endif
+
+                DMAResource_DestroyRecord(Handle);
+                LOG_CRIT(
+                    "DMAResource_Alloc: "
+                    "Failed to obtain DMA address for host address 0x%p, "
+                    "for handle 0x%p\n",
+                    AlignedAddr_p,
+                    Handle);
+
+                return -1;
+            }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Alloc: Handle 0x%p, "
+                     "bus address allocated/adjusted 0x%p / 0x%p\n",
+                     Handle,
+                     (void*)DMAAddr,
+                     (void*)(DMAAddr - HWPAL_DMARESOURCE_BANK_STATIC_OFFSET));
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+            DMAAddr -= HWPAL_DMARESOURCE_BANK_STATIC_OFFSET;
+        }
+
+        // put the bus address first, presumably being the most
+        // frequently looked-up domain.
+        Pair_p = Rec_p->AddrPairs;
+        Pair_p->Address_p = (void *)(uintptr_t)DMAAddr;
+        Pair_p->Domain = DMARES_DOMAIN_BUS;
+
+        ++Pair_p;
+        Pair_p->Address_p = AlignedAddr_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST;
+
+        // Return this address
+        *AddrPair_p = *Pair_p;
+
+        // This host address will be used for freeing the allocated buffer
+        ++Pair_p;
+        Pair_p->Address_p = UnalignedAddr_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST_UNALIGNED;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+        LOG_INFO("DMAResource_Alloc (1/2): handle = 0x%p, allocator='%c', "
+                 "size allocated/requested=%d/%d, \n"
+                 "DMAResource_Alloc (2/2): alignment/bank/cached=%d/%d/%d, "
+                 "bus addr=0x%p, host addr un-/aligned=0x%p/0x%p\n",
+                 Handle, Rec_p->AllocatorRef,
+                 Rec_p->BufferSize, Rec_p->Props.Size,
+                 Rec_p->Props.Alignment,Rec_p->Props.Bank,Rec_p->Props.fCached,
+                 (void*)DMAAddr,UnalignedAddr_p,AlignedAddr_p);
+#endif
+    } // Allocated DMA resource
+
+    // return results
+    *Handle_p = Handle;
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Release
+ */
+int
+HWPAL_DMAResource_Release(
+        const DMAResource_Handle_t Handle)
+{
+    DMAResource_Record_t * Rec_p;
+    dma_addr_t DMAAddr = 0;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+    void* UnalignedAddr_p = NULL;
+#endif
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_Release: "
+            "Invalid handle %p\n",
+            Handle);
+        return -1;
+    }
+
+    // request the kernel to unmap the DMA resource
+    if (Rec_p->AllocatorRef == 'A' || Rec_p->AllocatorRef == 'k' ||
+        Rec_p->AllocatorRef == 'R')
+    {
+        DMAResource_AddrPair_t * Pair_p;
+        struct device * DMADevice_p;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_BUS);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_Release: "
+                "No bus address found for Handle %p?\n",
+                Handle);
+            return -1;
+        }
+
+        DMAAddr = (dma_addr_t)(uintptr_t)Pair_p->Address_p;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p,
+                                             DMARES_DOMAIN_HOST_UNALIGNED);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_Release: "
+                "No host address found for Handle %p?\n",
+                Handle);
+            return -1;
+        }
+
+        // Get device reference for this resource
+        DMADevice_p = Device_GetReference(NULL, NULL);
+
+#ifndef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+#ifndef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+        if(Rec_p->AllocatorRef != 'R' &&
+           Rec_p->BankType != HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+        {
+            dma_unmap_single(DMADevice_p,
+                             DMAAddr + HWPAL_DMARESOURCE_BANK_STATIC_OFFSET,
+                             Rec_p->BufferSize, DMA_BIDIRECTIONAL);
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Release: Handle 0x%p, "
+                     "bus address freed/adjusted 0x%p / 0x%p\n",
+                     Handle,
+                     (void*)(DMAAddr + HWPAL_DMARESOURCE_BANK_STATIC_OFFSET),
+                     (void*)DMAAddr);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+        }
+#endif // !HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+        if(Rec_p->AllocatorRef == 'A')
+        {
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+            #ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Release: Handle 0x%p, "
+                     "bus address freed/adjusted 0x%p / 0x%p\n",
+                     Handle,
+                     (void*)(DMAAddr + HWPAL_DMARESOURCE_BANK_STATIC_OFFSET),
+                     (void*)DMAAddr);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+            dma_free_coherent(DMADevice_p,
+                              Rec_p->BufferSize,
+                              Pair_p->Address_p,
+                              DMAAddr + HWPAL_DMARESOURCE_BANK_STATIC_OFFSET);
+#else
+            if (Rec_p->BankType == HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR)
+            {
+                Device_Data_t DevData;
+
+                ZEROINIT(DevData);
+                Device_GetReference(NULL, &DevData);
+
+                iounmap((void __iomem *)Pair_p->Address_p);
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+                LOG_INFO("DMAResource_Release: Handle 0x%p, "
+                         "bus address freed/adjusted 0x%p / 0x%p\n",
+                         Handle,
+                         (void*)(DMAAddr + (phys_addr_t)DevData.PhysAddr +
+                                     HWPAL_DMARESOURCE_BANK_STATIC_OFFSET),
+                         (void*)DMAAddr);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+                release_mem_region(DMAAddr + (phys_addr_t)(uintptr_t)DevData.PhysAddr +
+                                     HWPAL_DMARESOURCE_BANK_STATIC_OFFSET,
+                                   Rec_p->BufferSize);
+            }
+            else
+                kfree(Pair_p->Address_p);
+#endif
+        }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+        UnalignedAddr_p = Pair_p->Address_p;
+#endif
+    }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+    LOG_INFO("DMAResource_Release (1/2): "
+             "handle = 0x%p, allocator='%c', "
+             "size allocated/requested=%d/%d, \n"
+             "DMAResource_Release (2/2): "
+             "alignment/bank/cached=%d/%d/%d, "
+             "bus addr=0x%p, unaligned host addr=0x%p\n",
+             Handle, Rec_p->AllocatorRef,
+             Rec_p->BufferSize, Rec_p->Props.Size,
+             Rec_p->Props.Alignment, Rec_p->Props.Bank, Rec_p->Props.fCached,
+             (void*)DMAAddr, UnalignedAddr_p);
+#endif
+
+    // free administration resources
+    Rec_p->Magic = 0;
+    DMAResource_DestroyRecord(Handle);
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Init
+ */
+bool
+HWPAL_DMAResource_Init(void)
+{
+    bool AllocFailed = false;
+    unsigned int MaxHandles = HWPAL_DMA_NRESOURCES;
+
+    {
+        struct device * DMADevice_p;
+        int res;
+
+
+        // Get device reference for this resource
+        DMADevice_p = Device_GetReference(NULL, NULL);
+
+        LOG_INFO("%s: Device DMA address mask 0x%016Lx\n",
+                 __func__,
+                 (long long unsigned int)HWPAL_DMARESOURCE_ADDR_MASK);
+
+        // Set DMA mask wider, so the DMA API will not try to bounce
+        res = HWPAL_DMARESOURCE_SET_MASK(DMADevice_p,
+                                         HWPAL_DMARESOURCE_ADDR_MASK);
+        if ( res != 0)
+        {
+            LOG_CRIT("%s: failed, host does not support DMA address "
+                     "mask 0x%016Lx\n",
+                     __func__,
+                     (long long unsigned int)HWPAL_DMARESOURCE_ADDR_MASK);
+            return false;
+        }
+    }
+
+    // already initialized?
+    if (HandlesCount != 0)
+        return false;
+
+    HWPAL_Lock_p = HWPAL_DMAResource_Lock_Alloc();
+    if (HWPAL_Lock_p == NULL)
+    {
+        LOG_CRIT("HWPAL_DMAResource_Init: record lock allocation failed\n");
+        return false;
+    }
+
+    ChunksCount = (MaxHandles + MAX_RECORDS_PER_CHUNK - 1) /
+        MAX_RECORDS_PER_CHUNK;
+
+    if (ChunksCount > 65535 ||
+        ChunksCount * sizeof(void *) > KMALLOC_MAX_SIZE)
+    {
+        LOG_CRIT(
+            "HWPAL_DMAResource_Init: "
+            "Too many chunks desired: %u\n",
+            ChunksCount);
+        return false;
+    }
+
+    LOG_INFO(
+         "HWPAL_DMAResource_Init: "
+         "Allocate %d records in %d chunks, "
+         "DMA address size (bytes) %d, host address size  (bytes) %d\n",
+         MaxHandles, ChunksCount,
+         (int)sizeof(dma_addr_t),
+         (int)sizeof(void*));
+
+    LOG_INFO("HWPAL_DMAResource_Init: D-cache line size %d\n",
+             HWPAL_DMARESOURCE_DCACHE_LINE_SIZE);
+
+#ifdef HWPAL_64BIT_HOST
+    if (sizeof(void*) != 8 || sizeof(long) < 8)
+    {
+        LOG_CRIT("\n\nHWPAL_DMAResource_Init: ERROR, 64-bit host specified, "
+                 "but data sizes do not agree\n");
+        return false;
+    }
+#else
+    if (sizeof(void*) != 4)
+    {
+        LOG_CRIT("\n\nHWPAL_DMAResource_Init: ERROR, 32-bit host specified, "
+                 "but data sizes do not agree\n");
+        return false;
+    }
+#endif
+
+    if (sizeof(dma_addr_t) > sizeof(void*))
+    {
+        LOG_WARN(
+            "\n\nHWPAL_DMAResource_Init: WARNING, "
+            "unsupported host DMA address size %d\n\n",
+            (int)sizeof(dma_addr_t));
+    }
+
+    RecordChunkPtrs_p =
+            HWPAL_DMAResource_MemAlloc(ChunksCount * sizeof(void *));
+    if (RecordChunkPtrs_p)
+    {
+        // Allocate each of the chunks in the RecordChunkPtrs_p array,
+        // all of size MAX_RECORDS_PER_CHUNK, except the last one.
+        int RecordsLeft, RecordsThisChunk, i;
+
+        // Pre-initialize with null, in case of early error exit
+        memset(
+            RecordChunkPtrs_p,
+            0,
+            ChunksCount * sizeof(DMAResource_Record_t*));
+
+        i=0;
+        RecordsLeft = MaxHandles;
+
+        while ( RecordsLeft )
+        {
+            if (RecordsLeft > MAX_RECORDS_PER_CHUNK)
+                RecordsThisChunk = MAX_RECORDS_PER_CHUNK;
+            else
+                RecordsThisChunk = RecordsLeft;
+
+            RecordChunkPtrs_p[i] =
+                    HWPAL_DMAResource_MemAlloc(RecordsThisChunk *
+                                            sizeof(DMAResource_Record_t));
+            if( RecordChunkPtrs_p[i] == NULL )
+            {
+                LOG_CRIT(
+                    "HWPAL_DMAResource_Init:"
+                    "Allocation failed chunk %d\n",i);
+                AllocFailed = true;
+                break;
+            }
+
+            RecordsLeft -= RecordsThisChunk;
+            i++;
+        }
+        LOG_INFO(
+            "HWPAL_DMAResource_Init:"
+            "Allocated %d chunks last one=%d others=%d, total=%d\n",
+            i,
+            RecordsThisChunk,
+            (int)MAX_RECORDS_PER_CHUNK,
+            (int)((i-1) * MAX_RECORDS_PER_CHUNK + RecordsThisChunk));
+    }
+
+    if (MaxHandles * sizeof(uint32_t) > KMALLOC_MAX_SIZE)
+    { // Too many handles for kmalloc, allocate with get_free_pages.
+        int order = get_order(MaxHandles * sizeof(uint32_t));
+
+	pr_notice("FreeHandles: get_free_page\n");
+        LOG_INFO(
+             "HWPAL_DMAResource_Init: "
+             "Handles & freelist allocated by get_free_pages order=%d\n",
+             order);
+
+        Handles_p = (void*) __get_free_pages(GFP_KERNEL, order);
+        FreeHandles.Nrs_p = (void*) __get_free_pages(GFP_KERNEL, order);
+        FreeRecords.Nrs_p = (void*) __get_free_pages(GFP_KERNEL, order);
+    }
+    else
+    {
+	pr_notice("FreeHandles: kmalloc\n");
+        Handles_p = HWPAL_DMAResource_MemAlloc(MaxHandles * sizeof(uint32_t));
+        FreeHandles.Nrs_p =
+                HWPAL_DMAResource_MemAlloc(MaxHandles * sizeof(uint32_t));
+        FreeRecords.Nrs_p =
+                HWPAL_DMAResource_MemAlloc(MaxHandles * sizeof(uint32_t));
+    }
+
+    // if any allocation failed, free the whole lot
+    if (RecordChunkPtrs_p == NULL ||
+        Handles_p == NULL ||
+        FreeHandles.Nrs_p == NULL ||
+        FreeRecords.Nrs_p == NULL ||
+        AllocFailed)
+    {
+        LOG_CRIT(
+            "HWPAL_DMAResource_Init: "
+            "RP=%p HP=%p FH=%p FR=%p AF=%d\n",
+            RecordChunkPtrs_p,
+            Handles_p,
+            FreeHandles.Nrs_p,
+            FreeRecords.Nrs_p,
+            AllocFailed);
+
+        if (RecordChunkPtrs_p)
+        {
+            int i;
+            for (i = 0; i < ChunksCount; i++)
+            {
+                if(RecordChunkPtrs_p[i])
+                    HWPAL_DMAResource_MemFree(RecordChunkPtrs_p[i]);
+            }
+            HWPAL_DMAResource_MemFree(RecordChunkPtrs_p);
+        }
+
+        if (MaxHandles * sizeof(uint32_t) > KMALLOC_MAX_SIZE)
+        { // Were allocated with get_free pages.
+            int order = get_order(MaxHandles * sizeof(uint32_t));
+
+            if (Handles_p)
+                free_pages((unsigned long)Handles_p, order);
+
+            if (FreeHandles.Nrs_p)
+                free_pages((unsigned long)FreeHandles.Nrs_p, order);
+
+            if (FreeRecords.Nrs_p)
+                free_pages((unsigned long)FreeRecords.Nrs_p, order);
+        }
+        else
+        {
+            if (Handles_p)
+                HWPAL_DMAResource_MemFree(Handles_p);
+
+            if (FreeHandles.Nrs_p)
+                HWPAL_DMAResource_MemFree(FreeHandles.Nrs_p);
+
+            if (FreeRecords.Nrs_p)
+                HWPAL_DMAResource_MemFree(FreeRecords.Nrs_p);
+        }
+        RecordChunkPtrs_p = NULL;
+        Handles_p = NULL;
+        FreeHandles.Nrs_p = NULL;
+        FreeRecords.Nrs_p = NULL;
+
+        if (HWPAL_Lock_p != NULL)
+            HWPAL_DMAResource_Lock_Free(HWPAL_Lock_p);
+
+        return false;
+    }
+
+    // initialize the record numbers freelist
+    // initialize the handle numbers freelist
+    // initialize the handles array
+    {
+        unsigned int i;
+        unsigned int chunk=0;
+        unsigned int recidx=0;
+
+        for (i = 0; i < MaxHandles; i++)
+        {
+            Handles_p[i] = HWPAL_INVALID_INDEX;
+            FreeHandles.Nrs_p[i] = MaxHandles - 1 - i;
+            FreeRecords.Nrs_p[i] = COMPOSE_RECNR(chunk,recidx);
+            recidx++;
+            if(recidx == MAX_RECORDS_PER_CHUNK)
+            {
+                chunk++;
+                recidx = 0;
+            }
+        }
+
+        FreeHandles.ReadIndex = 0;
+        FreeHandles.WriteIndex = 0;
+
+        FreeRecords.ReadIndex = 0;
+        FreeRecords.WriteIndex = 0;
+    }
+
+    HandlesCount = MaxHandles;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_UnInit
+ *
+ * This function can be used to uninitialize the DMAResource administration.
+ * The caller must make sure that handles will not be used after this function
+ * returns.
+ * If memory was allocated by HWPAL_DMAResource_Init, this function will
+ * free it.
+ */
+void
+HWPAL_DMAResource_UnInit(void)
+{
+    // exit if not initialized
+    if (HandlesCount == 0)
+        return;
+
+    // find resource leaks
+#ifdef HWPAL_TRACE_DMARESOURCE_LEAKS
+    {
+        int i;
+        bool fFirstPrint = true;
+
+        for (i = 0; i < HandlesCount; i++)
+        {
+            uint32_t IdxPair = Handles_p[i];
+
+            if (IdxPair != HWPAL_INVALID_INDEX)
+            {
+                if (fFirstPrint)
+                {
+                    fFirstPrint = false;
+                    Log_FormattedMessage(
+                        "HWPAL_DMAResource_UnInit found leaking handles:\n");
+                }
+
+                Log_FormattedMessage(
+                    "Handle %p => "
+                    "Record %u\n",
+                    Handles_p + i,
+                    IdxPair);
+
+                {
+                    DMAResource_AddrPair_t * Pair_p;
+                    DMAResource_Record_t * Rec_p =
+                        DMAResourceLib_IdxPair2RecordPtr(IdxPair);
+
+                    if(Rec_p != NULL)
+                    {
+                        Pair_p = DMAResourceLib_LookupDomain(Rec_p,
+                                                          DMARES_DOMAIN_HOST);
+
+                        Log_FormattedMessage(
+                            "  AllocatedSize = %d\n"
+                            "  Alignment = %d\n"
+                            "  Bank = %d\n"
+                            "  BankType = %d\n"
+                            "  Host address = %p\n",
+                            Rec_p->BufferSize,
+                            Rec_p->Props.Alignment,
+                            Rec_p->Props.Bank,
+                            Rec_p->BankType,
+                            Pair_p->Address_p);
+                    }
+                    else
+                    {
+                        Log_FormattedMessage(" bad index pair\n");
+                    }
+                }
+            } // if
+        } // for
+
+        if (fFirstPrint)
+            Log_FormattedMessage(
+                "HWPAL_DMAResource_UnInit: no leaks found\n");
+    }
+#endif /* HWPAL_TRACE_DMARESOURCE_LEAKS */
+
+    {
+        int i;
+
+        for (i = 0; i < ChunksCount; i++)
+            HWPAL_DMAResource_MemFree(RecordChunkPtrs_p[i]);
+    }
+    HWPAL_DMAResource_MemFree(RecordChunkPtrs_p);
+
+    if (HandlesCount * sizeof(uint32_t) > KMALLOC_MAX_SIZE)
+    { // Were allocated with get_free pages.
+        int order = get_order(HandlesCount * sizeof(uint32_t));
+
+        free_pages((unsigned long)Handles_p, order);
+        free_pages((unsigned long)FreeHandles.Nrs_p, order);
+        free_pages((unsigned long)FreeRecords.Nrs_p, order);
+    }
+    else
+    {
+        HWPAL_DMAResource_MemFree(FreeHandles.Nrs_p);
+        HWPAL_DMAResource_MemFree(FreeRecords.Nrs_p);
+        HWPAL_DMAResource_MemFree(Handles_p);
+    }
+
+    if (HWPAL_Lock_p != NULL)
+        HWPAL_DMAResource_Lock_Free(HWPAL_Lock_p);
+
+    FreeHandles.Nrs_p = NULL;
+    FreeRecords.Nrs_p = NULL;
+    Handles_p = NULL;
+    RecordChunkPtrs_p = NULL;
+
+    HandlesCount = 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_CheckAndRegister
+ */
+int
+HWPAL_DMAResource_CheckAndRegister(
+        const DMAResource_Properties_t RequestedProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        const char AllocatorRef,
+        DMAResource_Handle_t * const Handle_p)
+{
+    DMAResource_Properties_t ActualProperties = RequestedProperties;
+    DMAResource_AddrPair_t * Pair_p;
+    DMAResource_Record_t * Rec_p;
+    DMAResource_Handle_t Handle;
+    dma_addr_t DMAAddr = 0;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+    void* HostAddr = NULL;
+#endif
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if(AllocatorRef != 'N' &&
+       ((uintptr_t)AddrPair.Address_p & (ActualProperties.Alignment - 1)) !=0)
+    {
+        // Warn against unaligned addresses, but do not fail.
+        LOG_WARN("DMAResource_CheckAndRegister: "
+                 "address not aligned to %d\n",ActualProperties.Alignment);
+        ActualProperties.Alignment = 1;
+    }
+
+    if (NULL == Handle_p)
+    {
+        return -1;
+    }
+
+    if (!DMAResourceLib_IsSaneInput(&AddrPair,
+                                    &AllocatorRef,
+                                    &ActualProperties))
+    {
+        return 1;
+    }
+
+    if (AddrPair.Domain != DMARES_DOMAIN_HOST)
+    {
+        LOG_WARN(
+            "HWPAL_DMAResource_CheckAndRegister: "
+            "Unsupported domain: %u\n",
+            AddrPair.Domain);
+        return 1;
+    }
+#endif
+
+    if (AllocatorRef != 'k' && AllocatorRef != 'R' &&
+        AllocatorRef != 'N' && AllocatorRef != 'C')
+    {
+        LOG_WARN(
+            "HWPAL_DMAResource_CheckAndRegister: "
+            "Unsupported AllocatorRef: %c\n",
+            AllocatorRef);
+
+        return 1;
+    }
+
+    // allocate record -> Handle & Rec_p
+    Handle = DMAResource_CreateRecord();
+    if (Handle == NULL)
+    {
+        return -1;
+    }
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        return -1;
+    }
+
+#ifdef HWPAL_ARCH_COHERENT
+    ActualProperties.fCached    = false;
+#else
+    ActualProperties.fCached    = RequestedProperties.fCached;
+#endif // HWPAL_ARCH_COHERENT
+
+#ifdef HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+    ActualProperties.fCached    = false;
+#endif // HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+    if (AllocatorRef == 'k' &&
+        ((uintptr_t)AddrPair.Address_p &
+          (HWPAL_DMAResource_DCache_Alignment_Get()-1)) != 0)
+    {
+        DMAResource_DestroyRecord(Handle);
+        LOG_CRIT("DMAResource_CheckAndRegister: "
+                 "address not aligned to cache line size %d\n",
+                 HWPAL_DMAResource_DCache_Alignment_Get());
+        return -1;
+    }
+
+
+    DMAResourceLib_Setup_Record(
+            &ActualProperties,
+            AllocatorRef,
+            Rec_p,
+            ActualProperties.Size);
+
+    Pair_p = Rec_p->AddrPairs;
+    if (AllocatorRef == 'k' || AllocatorRef == 'R')
+    {
+        struct device * DMADevice_p;
+
+        // Get device reference for this resource
+        DMADevice_p = Device_GetReference(NULL, NULL);
+
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        if (!is_kernel_addr ((unsigned long)AddrPair.Address_p))
+        {
+            DMAResource_DestroyRecord(Handle);
+            LOG_WARN(
+                "HWPAL_DMAResource_CheckAndRegister: "
+                "Unsupported host address: 0x%p\n",
+                AddrPair.Address_p);
+
+            return -1;
+        }
+
+        DMAAddr = (dma_addr_t)virt_to_phys (AddrPair.Address_p);
+#else
+        if (AllocatorRef == 'k')
+        {
+            // Note: this function can create a bounce buffer!
+            DMAAddr = dma_map_single(DMADevice_p,
+                                     AddrPair.Address_p,
+                                     ActualProperties.Size,
+                                     DMA_BIDIRECTIONAL);
+            if (dma_mapping_error(DMADevice_p, DMAAddr))
+            {
+                if (DMAAddr)
+                    kfree(AddrPair.Address_p);
+
+                LOG_WARN(
+                    "HWPAL_DMAResource_CheckAndRegister: "
+                    "Failed to map DMA address for host address 0x%p, "
+                    "for handle 0x%p\n",
+                    AddrPair.Address_p,
+                    Handle);
+
+                return -1;
+            }
+
+            Rec_p->Props.fCached = true; // always cached for kmalloc()
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+            LOG_INFO("DMAResource_Alloc: Handle 0x%p, "
+                     "bus address requested/adjusted 0x%p / 0x%p\n",
+                     Handle,
+                     (void*)DMAAddr,
+                     (void*)(DMAAddr - HWPAL_DMARESOURCE_BANK_STATIC_OFFSET));
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+
+            DMAAddr -= HWPAL_DMARESOURCE_BANK_STATIC_OFFSET;
+        }
+        else if (AllocatorRef == 'R')
+        {
+            DMAResource_Record_t * ParentRec_p;
+            DMAResource_AddrPair_t *ParentHostPair_p,*ParentBusPair_p;
+            uint32_t SubsetOffset;
+
+            ParentRec_p = DMAResourceLib_Find_Matching_DMAResource(
+                                                        &ActualProperties,
+                                                        AddrPair);
+            if (ParentRec_p == NULL)
+            {
+                DMAAddr = 0;
+                LOG_CRIT("HWPAL_DMAResource_CheckAndRegister: "
+                         "Failed to match DMA resource, "
+                         "alignment/bank/size %d/%d/%d, host addr 0x%p\n",
+                         ActualProperties.Alignment,
+                         ActualProperties.Bank,
+                         ActualProperties.Size,
+                         AddrPair.Address_p);
+            }
+            else
+            {
+                Rec_p->Props.fCached = ParentRec_p->Props.fCached;
+                Rec_p->BankType      = ParentRec_p->BankType;
+
+                ParentHostPair_p = DMAResourceLib_LookupDomain(
+                                                           ParentRec_p,
+                                                           DMARES_DOMAIN_HOST);
+
+                ParentBusPair_p = DMAResourceLib_LookupDomain(
+                                                            ParentRec_p,
+                                                            DMARES_DOMAIN_BUS);
+
+                if (ParentHostPair_p == NULL || ParentBusPair_p == NULL)
+                {
+                    DMAAddr = 0;
+                    LOG_CRIT("HWPAL_DMAResource_CheckAndRegister: "
+                             "Failed to lookup parent DMA domain, "
+                             "alignment/bank/size %d/%d/%d, "
+                             "domain host/bus %p/%p\n",
+                             ActualProperties.Alignment,
+                             ActualProperties.Bank,
+                             ActualProperties.Size,
+                             ParentHostPair_p,
+                             ParentBusPair_p);
+                }
+                else
+                {
+                    SubsetOffset = (uint32_t)((uint8_t *)AddrPair.Address_p -
+                                       (uint8_t *)ParentHostPair_p->Address_p);
+                    DMAAddr = (dma_addr_t)(uintptr_t)ParentBusPair_p->Address_p +
+                                                                SubsetOffset;
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+                    LOG_INFO("HWPAL_DMAResource_CheckAndRegister: "
+                             "Registered subset buffer, "
+                             "parent bus addr 0x%p, child offset %u\n",
+                             ParentBusPair_p->Address_p,
+                             SubsetOffset);
+#endif // HWPAL_TRACE_DMARESOURCE_BUF
+                }
+            }
+        }
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+        if (0 == DMAAddr)
+        {
+            DMAResource_DestroyRecord(Handle);
+            LOG_CRIT("HWPAL_DMAResource_CheckAndRegister: "
+                     "Failed to obtain DMA address for host address 0x%p, "
+                     "for handle 0x%p\n",
+                     AddrPair.Address_p,
+                     Handle);
+
+            return -1;
+        }
+
+        Pair_p->Address_p = (void *)(uintptr_t)DMAAddr;
+        Pair_p->Domain = DMARES_DOMAIN_BUS;
+
+        ++Pair_p;
+        Pair_p->Address_p = AddrPair.Address_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST;
+
+        // This host address will be used for freeing the allocated buffer
+        ++Pair_p;
+        Pair_p->Address_p = AddrPair.Address_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST_UNALIGNED;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+        HostAddr = AddrPair.Address_p;
+#endif
+    }
+    else if (AllocatorRef == 'N' || AllocatorRef == 'C')
+    {
+        Pair_p->Address_p = AddrPair.Address_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST;
+
+        // This host address will be used for freeing the allocated buffer
+        ++Pair_p;
+        Pair_p->Address_p = AddrPair.Address_p;
+        Pair_p->Domain = DMARES_DOMAIN_HOST_UNALIGNED;
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+        HostAddr = AddrPair.Address_p;
+        DMAAddr = 0;
+#endif
+    }
+
+#ifdef HWPAL_TRACE_DMARESOURCE_BUF
+    LOG_INFO("HWPAL_DMAResource_CheckAndRegister (1/2): "
+             "handle = 0x%p, allocator='%c', "
+             "size allocated/requested=%d/%d, \n"
+             "HWPAL_DMAResource_CheckAndRegister (2/2): "
+             "alignment/bank/cached=%d/%d/%d, "
+             "bus addr=0x%p, host addr=0x%p\n",
+             Handle, Rec_p->AllocatorRef,
+             Rec_p->BufferSize, Rec_p->Props.Size,
+             Rec_p->Props.Alignment, Rec_p->Props.Bank, Rec_p->Props.fCached,
+             (void*)DMAAddr, HostAddr);
+#endif
+
+    *Handle_p = Handle;
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Record_Update
+ */
+int
+HWPAL_DMAResource_Record_Update(
+        const int Identifier,
+        DMAResource_Record_t * const Rec_p)
+{
+    IDENTIFIER_NOT_USED(Identifier);
+    IDENTIFIER_NOT_USED(Rec_p);
+
+    return 0; // Success, empty implementation
+}
+
+/*----------------------------------------------------------------------------
+ * DMAResource_CreateRecord
+ *
+ * This function can be used to create a record. The function returns a handle
+ * for the record. Use DMAResource_Handle2RecordPtr to access the record.
+ * Destroy the record when no longer required, see DMAResource_Destroy.
+ * This function initializes the record to all zeros.
+ *
+ * Return Values
+ *     Handle for the DMA Resource.
+ *     NULL is returned when the creation failed.
+ */
+DMAResource_Handle_t
+DMAResource_CreateRecord(void)
+{
+    unsigned long flags;
+    uint32_t HandleNr;
+    uint32_t IdxPair = 0;
+
+    // return NULL when not initialized
+    if (HandlesCount == 0)
+        return NULL;
+
+    HWPAL_DMAResource_Lock_Acquire(HWPAL_Lock_p, &flags);
+
+    HandleNr = DMAResourceLib_FreeList_Get(&FreeHandles);
+    if (HandleNr != HWPAL_INVALID_INDEX)
+    {
+        IdxPair = DMAResourceLib_FreeList_Get(&FreeRecords);
+        if (IdxPair == HWPAL_INVALID_INDEX)
+        {
+            DMAResourceLib_FreeList_Add(&FreeHandles, HandleNr);
+            HandleNr = HWPAL_INVALID_INDEX;
+        }
+    }
+
+    HWPAL_DMAResource_Lock_Release(HWPAL_Lock_p, &flags);
+
+    // return NULL when reservation failed
+    if (HandleNr == HWPAL_INVALID_INDEX)
+    {
+        LOG_CRIT("DMAResource_Create_Record: "
+                 "reservation failed, out of handles\n");
+        return NULL;
+    }
+
+    // initialize the record
+    {
+        DMAResource_Record_t * Rec_p =
+                DMAResourceLib_IdxPair2RecordPtr(IdxPair);
+        if(Rec_p == NULL)
+        {
+            LOG_CRIT(
+                "DMAResource_Create_Record: "
+                "Bad index pair returned %u\n",IdxPair);
+            return NULL;
+        }
+        memset(Rec_p, 0, sizeof(DMAResource_Record_t));
+        Rec_p->Magic = DMARES_RECORD_MAGIC;
+    }
+
+    // initialize the handle
+    Handles_p[HandleNr] = IdxPair;
+
+    // fill in the handle position
+    return Handles_p + HandleNr;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_DestroyRecord
+ *
+ * This function invalidates the handle and the record instance.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (Alloc/Register/Attach).
+ *
+ * Return Values
+ *     None
+ */
+void
+DMAResource_DestroyRecord(
+        const DMAResource_Handle_t Handle)
+{
+    if (DMAResource_IsValidHandle(Handle))
+    {
+        uint32_t * p = (uint32_t *)Handle;
+        uint32_t IdxPair = *p;
+
+        if (DMAResourceLib_IdxPair2RecordPtr(IdxPair) != NULL)
+        {
+            unsigned long flags;
+            int HandleNr = p - Handles_p;
+
+            // note handle is no longer value
+            *p = HWPAL_INVALID_INDEX;
+
+            HWPAL_DMAResource_Lock_Acquire(HWPAL_Lock_p, &flags);
+
+            // add the HandleNr and IdxPair to respective LRU lists
+            DMAResourceLib_FreeList_Add(&FreeHandles, HandleNr);
+            DMAResourceLib_FreeList_Add(&FreeRecords, IdxPair);
+
+            HWPAL_DMAResource_Lock_Release(HWPAL_Lock_p, &flags);
+        }
+        else
+        {
+            LOG_WARN(
+                "DMAResource_Destroy: "
+                "Handle %p was already destroyed\n",
+                Handle);
+        }
+    }
+    else
+    {
+        LOG_WARN(
+            "DMAResource_Destroy: "
+            "Invalid handle %p\n",
+            Handle);
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_IsValidHandle
+ *
+ * This function tells whether a handle is valid.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (Alloc/Register/Attach).
+ *
+ * Return Value
+ *     true   The handle is valid
+ *     false  The handle is NOT valid
+ */
+bool
+DMAResource_IsValidHandle(
+        const DMAResource_Handle_t Handle)
+{
+    uint32_t * p = (uint32_t *)Handle;
+
+    if (p < Handles_p ||
+        p >= Handles_p + HandlesCount)
+    {
+        return false;
+    }
+
+    // check that the handle has not been destroyed yet
+    if (*p == HWPAL_INVALID_INDEX)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Handle2RecordPtr
+ *
+ * This function can be used to get a pointer to the DMA resource record
+ * (DMAResource_Record_t) for the provided handle. The pointer is valid until
+ * the record and handle are destroyed.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (Alloc/Register/Attach).
+ *
+ * Return Value
+ *     Pointer to the DMAResource_Record_t memory for this handle.
+ *     NULL is returned if the handle is invalid.
+ */
+DMAResource_Record_t *
+DMAResource_Handle2RecordPtr(
+        const DMAResource_Handle_t Handle)
+{
+    uint32_t * p = (uint32_t *)Handle;
+
+#ifdef HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+    if(!DMAResource_IsValidHandle(Handle))
+    {
+        return NULL;
+    }
+
+    if (p != NULL)
+    {
+        uint32_t IdxPair = *p;
+
+        DMAResource_Record_t* Rec_p =
+                DMAResourceLib_IdxPair2RecordPtr(IdxPair);
+
+        if(Rec_p != NULL && Rec_p->Magic == DMARES_RECORD_MAGIC)
+        {
+            return Rec_p; // ## RETURN ##
+        }
+        else
+        {
+            return NULL; // ## RETURN ##
+        }
+    }
+#else
+    return RecordChunkPtrs_p[CHUNK_OF(*p)] + RECIDX_OF(*p);
+#endif
+
+    return NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_PreDMA
+ */
+void
+DMAResource_PreDMA(
+        const DMAResource_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const unsigned int ByteCount)
+{
+    DMAResource_Record_t *Rec_p;
+    unsigned int NBytes = ByteCount;
+    unsigned int Offset = ByteOffset;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_PreDMA: "
+            "Invalid handle %p\n",
+            Handle);
+        return;
+    }
+
+    if (NBytes == 0)
+    {
+        // Prepare the whole resource for the DMA operation
+        NBytes = Rec_p->Props.Size;
+        Offset = 0;
+    }
+
+    if ((Offset >= Rec_p->Props.Size) ||
+        (NBytes > Rec_p->Props.Size) ||
+        (Offset + NBytes > Rec_p->Props.Size))
+    {
+        LOG_CRIT(
+            "DMAResource_PreDMA: "
+            "Invalid range 0x%08x-0x%08x (not in 0x0-0x%08x)\n",
+            ByteOffset,
+            ByteOffset + ByteCount,
+            Rec_p->Props.Size);
+        return;
+    }
+
+    if (Rec_p->Props.fCached &&
+        (Rec_p->AllocatorRef == 'k' || Rec_p->AllocatorRef == 'A' ||
+         Rec_p->AllocatorRef == 'R'))
+    {
+        DMAResource_AddrPair_t * Pair_p;
+
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        dma_addr_t DMAAddr;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_PreDMA: "
+                "No host address found for Handle %p?\n",
+                Handle);
+
+            return;
+        }
+
+        DMAAddr = (dma_addr_t)Pair_p->Address_p;
+#else
+        dma_addr_t DMAAddr;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_BUS);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_PreDMA: "
+                "No bus address found for Handle %p?\n",
+                Handle);
+
+            return;
+        }
+
+        DMAAddr = (dma_addr_t)(uintptr_t)Pair_p->Address_p;
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        IDENTIFIER_NOT_USED(DMAAddr);
+
+#ifdef HWPAL_TRACE_DMARESOURCE_PREPOSTDMA
+        Log_FormattedMessage(
+            "DMAResource_PreDMA: "
+            "Handle=%p, "
+            "offset=%u, size=%u, "
+            "allocator='%c', "
+            "addr=0x%p\n",
+            Handle,
+            Offset, NBytes,
+            Rec_p->AllocatorRef,
+            (void*)DMAAddr);
+#endif
+
+#ifndef HWPAL_ARCH_COHERENT
+        {
+            struct device * DMADevice_p;
+            size_t size = NBytes;
+
+            // Get device reference for this resource
+            DMADevice_p = Device_GetReference(NULL, NULL);
+
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+            {
+                uint8_t* DMABuffer_p = (uint8_t*)DMAAddr;
+
+                dma_cache_sync(DMADevice_p, DMABuffer_p + Offset,
+                               size, DMA_TO_DEVICE);
+            }
+#else
+            dma_sync_single_range_for_device(DMADevice_p, DMAAddr,
+                    Offset, size, DMA_BIDIRECTIONAL);
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        }
+#endif
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_PostDMA
+ */
+void
+DMAResource_PostDMA(
+        const DMAResource_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const unsigned int ByteCount)
+{
+    DMAResource_Record_t *Rec_p;
+    unsigned int NBytes = ByteCount;
+    unsigned int Offset = ByteOffset;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+    if (Rec_p == NULL)
+    {
+        LOG_WARN(
+            "DMAResource_PostDMA: "
+            "Invalid handle %p\n",
+            Handle);
+        return;
+    }
+
+    if (NBytes == 0)
+    {
+        // Prepare the whole resource for the DMA operation
+        NBytes = Rec_p->Props.Size;
+        Offset = 0;
+    }
+
+    if ((ByteOffset >= Rec_p->Props.Size) ||
+        (NBytes > Rec_p->Props.Size) ||
+        (ByteOffset + NBytes > Rec_p->Props.Size))
+    {
+        LOG_CRIT(
+            "DMAResource_PostDMA: "
+            "Invalid range 0x%08x-0x%08x (not in 0x0-0x%08x)\n",
+            ByteOffset,
+            ByteOffset + NBytes,
+            Rec_p->Props.Size);
+        return;
+    }
+
+    if (Rec_p->Props.fCached &&
+        (Rec_p->AllocatorRef == 'k' || Rec_p->AllocatorRef == 'A' ||
+         Rec_p->AllocatorRef == 'R'))
+    {
+        DMAResource_AddrPair_t * Pair_p;
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        dma_addr_t DMAAddr;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_HOST);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_PostDMA: "
+                "No host address found for Handle %p?\n",
+                Handle);
+
+            return;
+        }
+
+        DMAAddr = (dma_addr_t)Pair_p->Address_p;
+#else
+        dma_addr_t DMAAddr;
+
+        Pair_p = DMAResourceLib_LookupDomain(Rec_p, DMARES_DOMAIN_BUS);
+        if (Pair_p == NULL)
+        {
+            LOG_WARN(
+                "DMAResource_PostDMA: "
+                "No bus address found for Handle %p?\n",
+                Handle);
+
+            return;
+        }
+
+        DMAAddr = (dma_addr_t)(uintptr_t)Pair_p->Address_p;
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+        IDENTIFIER_NOT_USED(DMAAddr);
+        IDENTIFIER_NOT_USED(Offset);
+
+#ifdef HWPAL_TRACE_DMARESOURCE_PREPOSTDMA
+        Log_FormattedMessage(
+            "DMAResource_PostDMA: "
+            "Handle=%p, "
+            "offset=%u, size=%u), "
+            "allocator='%c', "
+            "addr 0x%p\n",
+            Handle,
+            Offset, NBytes,
+            Rec_p->AllocatorRef,
+            (void*)DMAAddr);
+#endif
+
+#ifndef HWPAL_ARCH_COHERENT
+        {
+            struct device * DMADevice_p;
+            size_t size = NBytes;
+
+            // Get device reference for this resource
+            DMADevice_p = Device_GetReference(NULL, NULL);
+
+#ifdef HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+            {
+                uint8_t* DMABuffer_p = (uint8_t*)DMAAddr;
+
+                dma_cache_sync(DMADevice_p, DMABuffer_p + Offset,
+                               size, DMA_FROM_DEVICE);
+            }
+#else
+            dma_sync_single_range_for_cpu(DMADevice_p, DMAAddr, Offset,
+                                          size, DMA_BIDIRECTIONAL);
+#endif // HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+        }
+#endif
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Attach
+ */
+int
+DMAResource_Attach(
+        const DMAResource_Properties_t ActualProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        DMAResource_Handle_t * const Handle_p)
+{
+    IDENTIFIER_NOT_USED(Handle_p);
+    IDENTIFIER_NOT_USED(AddrPair.Address_p);
+    IDENTIFIER_NOT_USED(ActualProperties.Alignment);
+
+    return -1; // Not implemented
+}
+
+
+/* end of file dmares_lkm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/device_lkm.c b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/device_lkm.c
new file mode 100644
index 0000000..5fac2e2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/device_lkm.c
@@ -0,0 +1,965 @@
+/* device_lkm.c
+ *
+ * This is the Linux Kernel-mode Driver Framework v4 Device API
+ * implementation for open Firmware. The implementation is device-agnostic and
+ * receives configuration details from the c_device_lkm.h file.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "device_mgmt.h"            // API to implement
+#include "device_rw.h"              // API to implement
+
+// Driver Framework Device Internal interface
+#include "device_internal.h"        // Device_Internal_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_device_lkm.h"
+
+// Driver Framework Device API
+#include "device_swap.h"            // Device_SwapEndian32
+
+// Driver Framework Device Platform interface
+#include "device_platform.h"        // Device_Platform_*
+
+#ifndef HWPAL_USE_UMDEVXS_DEVICE
+#ifdef HWPAL_DEVICE_USE_RPM
+// Runtime Power Management Kernel Macros API
+#include "rpm_kernel_macros.h"      // RPM_*
+#endif
+#endif
+
+// Logging API
+#include "log.h"                    // LOG_*
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"                   // memcmp
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t, NULL, inline, bool,
+                                    // IDENTIFIER_NOT_USED
+
+#ifdef HWPAL_USE_UMDEVXS_DEVICE
+#include "umdevxs_ofdev.h"
+#endif
+
+#ifndef HWPAL_USE_UMDEVXS_DEVICE
+// Linux Kernel Module interface
+#include "lkm.h"
+#endif
+
+// Linux Kernel API
+#include <linux/platform_device.h>  // platform_*,
+#include <asm/io.h>                 // ioread32, iowrite32
+#include <linux/compiler.h>         // __iomem
+#include <linux/slab.h>             // kmalloc, kfree
+#include <linux/hardirq.h>          // in_atomic
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define HWPAL_FLAG_READ     BIT_0   // 1
+#define HWPAL_FLAG_WRITE    BIT_1   // 2
+#define HWPAL_FLAG_SWAP     BIT_2   // 4
+#define HWPAL_FLAG_HA       BIT_5   // 32
+
+// c_device_lkm.h file defines a HWPAL_REMAP_ADDRESSES that
+// depends on HWPAL_REMAP_ONE
+#define HWPAL_REMAP_ONE(_old, _new) \
+    case _old: \
+        DeviceByteOffset = _new; \
+        break;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+// statically configured devices
+static const Device_Admin_Static_t HWPALLib_Devices_Static[] =
+{
+    HWPAL_DEVICES
+};
+
+// number of statically configured devices
+#define HWPAL_DEVICE_STATIC_COUNT \
+                (sizeof(HWPALLib_Devices_Static) \
+                            / sizeof(Device_Admin_Static_t))
+
+// All supported devices
+static Device_Admin_t * HWPALLib_Devices_p [HWPAL_DEVICE_COUNT];
+
+// Global administration data
+static Device_Global_Admin_t HWPALLib_Device_Global;
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_Hexdump
+ *
+ * This function hex-dumps an array of uint32_t.
+ */
+#if ((defined(HWPAL_TRACE_DEVICE_READ)) || (defined(HWPAL_TRACE_DEVICE_WRITE)))
+static void
+HWPAL_Hexdump(
+        const char * ArrayName_p,
+        const char * DeviceName_p,
+        const unsigned int ByteOffset,
+        const uint32_t * WordArray_p,
+        const unsigned int WordCount,
+        bool fSwapEndianness)
+{
+    unsigned int i;
+
+    Log_FormattedMessage(
+        "%s: "
+        "byte offsets 0x%x - 0x%x"
+        " (%s)\n"
+        "  ",
+        ArrayName_p,
+        ByteOffset,
+        ByteOffset + WordCount*4 -1,
+        DeviceName_p);
+
+    for (i = 1; i <= WordCount; i++)
+    {
+        uint32_t Value = WordArray_p[i - 1];
+
+        if (fSwapEndianness)
+            Value = Device_SwapEndian32(Value);
+
+        Log_FormattedMessage(" 0x%08x", Value);
+
+        if ((i & 7) == 0)
+            Log_Message("\n  ");
+    }
+
+    if ((WordCount & 7) != 0)
+        Log_Message("\n");
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Device_RemapDeviceAddress
+ *
+ * This function remaps certain device addresses (relative within the whole
+ * device address map) to other addresses. This is needed when the integration
+ * has remapped some EIP device registers to other addresses. The EIP Driver
+ * Libraries assume the devices always have the same internal layout.
+ */
+static inline unsigned int
+Device_RemapDeviceAddress(
+        unsigned int DeviceByteOffset)
+{
+#ifdef HWPAL_REMAP_ADDRESSES
+    switch(DeviceByteOffset)
+    {
+        // include the remap statements
+        HWPAL_REMAP_ADDRESSES
+
+        default:
+            break;
+    }
+#endif
+
+    return DeviceByteOffset;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPALLib_Device2RecPtr
+ *
+ * This function converts an Device_Handle_t received via one of the
+ * Device API functions into a HWPALLib_Devices_p record pointer, if it is
+ * valid.
+ *
+ * Return Value
+ *     NULL    Provided Device Handle was not valid
+ *     other   Pointer to a Device_Admin_t record
+ */
+static inline Device_Admin_t *
+HWPALLib_Device2RecordPtr(
+        Device_Handle_t Device)
+{
+    Device_Admin_t * p = (void *)Device;
+
+    if (p == NULL)
+        return NULL;
+
+#ifdef HWPAL_DEVICE_MAGIC
+    if (p->Magic != HWPAL_DEVICE_MAGIC)
+        return NULL;
+#endif
+
+    return p;
+}
+
+
+/*----------------------------------------------------------------------------
+ * HWPALLib_IsValid
+ *
+ * This function checks that the parameters are valid to make the access.
+ *
+ * Device_p is valid
+ * ByteOffset is 32-bit aligned
+ * ByteOffset is inside device memory range
+ */
+static inline bool
+HWPALLib_IsValid(
+        const Device_Admin_t * const Device_p,
+        const unsigned int ByteOffset)
+{
+    if (Device_p == NULL)
+        return false;
+
+    if (ByteOffset & 3)
+        return false;
+
+    if (Device_p->FirstOfs + ByteOffset > Device_p->LastOfs)
+        return false;
+
+    return true;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * device_internal interface
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Static_Count_Get
+ */
+unsigned int
+Device_Internal_Static_Count_Get(void)
+{
+    return HWPAL_DEVICE_STATIC_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Count_Get
+ */
+unsigned int
+Device_Internal_Count_Get(void)
+{
+    return HWPAL_DEVICE_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Static_Get
+ */
+const Device_Admin_Static_t *
+Device_Internal_Admin_Static_Get(void)
+{
+    return HWPALLib_Devices_Static;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Get
+ *
+ * Returns pointer to the memory location where the device list is stored.
+ *
+ */
+Device_Admin_t **
+Device_Internal_Admin_Get(void)
+{
+    return HWPALLib_Devices_p;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Global_Get
+ */
+Device_Global_Admin_t *
+Device_Internal_Admin_Global_Get(void)
+{
+    return &HWPALLib_Device_Global;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Alloc
+ */
+void *
+Device_Internal_Alloc(
+        unsigned int ByteCount)
+{
+    return kmalloc(ByteCount, in_atomic() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Free
+ */
+void
+Device_Internal_Free(
+        void * Ptr)
+{
+    kfree(Ptr);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_Initialize
+ */
+int
+Device_Internal_Initialize(
+        void * CustomInitData_p)
+{
+#ifndef HWPAL_USE_UMDEVXS_DEVICE
+    unsigned int i;
+    LKM_Init_t  LKMInit;
+
+    ZEROINIT(LKMInit);
+
+    LKMInit.DriverName_p        = HWPAL_DRIVER_NAME;
+    LKMInit.ResId               = HWPAL_DEVICE_RESOURCE_ID;
+    LKMInit.ResByteCount        = HWPAL_DEVICE_RESOURCE_BYTE_COUNT;
+    LKMInit.fRetainMap          = true;
+
+#ifdef HWPAL_DEVICE_USE_RPM
+    LKMInit.PM_p                = RPM_OPS_PM;
+#endif
+
+    if (LKM_Init(&LKMInit) < 0)
+    {
+        LOG_CRIT("%s: Failed to register the platform device\n", __func__);
+        return -1;
+    }
+
+    // Output default IRQ line number in custom data
+    {
+        int * p = (int *)CustomInitData_p;
+
+        int * IRQ_p = (int *)LKMInit.CustomInitData_p;
+
+        *p = IRQ_p[0];
+    }
+
+#ifdef HWPAL_DEVICE_USE_RPM
+    if (RPM_INIT_MACRO(LKM_DeviceGeneric_Get()) != RPM_SUCCESS)
+    {
+        LOG_CRIT("%s: RPM_Init() failed\n", __func__);
+        LKM_Uninit();
+        return -3; // error
+    }
+#endif
+
+    HWPALLib_Device_Global.Platform.MappedBaseAddr_p
+                                        = LKM_MappedBaseAddr_Get();
+    HWPALLib_Device_Global.Platform.Platform_Device_p
+                                        = LKM_DeviceSpecific_Get();
+    HWPALLib_Device_Global.Platform.PhysBaseAddr
+                                        = LKM_PhysBaseAddr_Get();
+
+    for(i = 0; i < HWPAL_DEVICE_COUNT; i++)
+        if (HWPALLib_Devices_p[i])
+        {
+            LOG_INFO("%s: mapped device '%s', "
+                     "virt base addr 0x%p, "
+                     "start byte offset 0x%x, "
+                     "last byte offset 0x%x\n",
+                     __func__,
+                     HWPALLib_Devices_p[i]->DevName,
+                     HWPALLib_Device_Global.Platform.MappedBaseAddr_p,
+                     HWPALLib_Devices_p[i]->FirstOfs,
+                     HWPALLib_Devices_p[i]->LastOfs);
+        }
+#else
+    UMDevXS_OFDev_GetDevice(
+           0,
+           &HWPALLib_Device_Global.Platform.Platform_Device_p,
+           (void __iomem **)&HWPALLib_Device_Global.Platform.MappedBaseAddr_p);
+
+    if (HWPALLib_Device_Global.Platform.Platform_Device_p == NULL ||
+            HWPALLib_Device_Global.Platform.MappedBaseAddr_p == NULL)
+    {
+        LOG_CRIT("%s: Failed, UMDevXS device %p, mapped address %p\n",
+                 __func__,
+                 HWPALLib_Device_Global.Platform.Platform_Device_p,
+                 HWPALLib_Device_Global.Platform.MappedBaseAddr_p);
+        return -1;
+    }
+
+    {
+        int * p = (int *)CustomInitData_p;
+
+        // Exported under GPL
+        *p = platform_get_irq(HWPALLib_Device_Global.Platform.Platform_Device_p,
+                              HWPAL_PLATFORM_IRQ_IDX);
+    }
+#endif // HWPAL_USE_UMDEVXS_DEVICE
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_UnInitialize
+ */
+void
+Device_Internal_UnInitialize(void)
+{
+#ifndef HWPAL_USE_UMDEVXS_DEVICE
+
+#ifdef HWPAL_DEVICE_USE_RPM
+    // Check if a race condition is possible here with auto-suspend timer
+    (void)RPM_UNINIT_MACRO();
+#endif
+
+    LKM_Uninit();
+#endif
+
+    // Reset global administration
+    ZEROINIT(HWPALLib_Device_Global);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_Find
+ */
+Device_Handle_t
+Device_Internal_Find(
+        const char * DeviceName_p,
+        const unsigned int Index)
+{
+    IDENTIFIER_NOT_USED(DeviceName_p);
+
+    // Return the device handle
+    return (Device_Handle_t)HWPALLib_Devices_p[Index];
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_GetIndex
+ */
+int
+Device_Internal_GetIndex(
+        const Device_Handle_t Device)
+{
+    Device_Admin_t * Device_p;
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    Device_p = HWPALLib_Device2RecordPtr(Device);
+#else
+    Device_p = Device;
+#endif
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (!HWPALLib_IsValid(Device_p, 0))
+    {
+        LOG_CRIT("%s: invalid device (%p) or ByteOffset (%u)\n",
+                 __func__,
+                 Device,
+                 0);
+        return -1;
+    }
+#endif
+
+    return Device_p->DeviceId;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * device_mgmt API
+ *
+ * These functions support finding a device given its name.
+ * A handle is returned that is needed in the device_rw API
+ * to read or write the device
+ */
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetReference
+ */
+Device_Reference_t
+Device_GetReference(
+        const Device_Handle_t Device,
+        Device_Data_t * const Data_p)
+{
+    Device_Reference_t DevReference;
+
+    // There exists only one reference for this implementation
+    IDENTIFIER_NOT_USED(Device);
+
+    if (!HWPALLib_Device_Global.fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return NULL;
+    }
+
+    // Return the platform device reference
+    // (pointer to the Linux device structure)
+    DevReference = &HWPALLib_Device_Global.Platform.Platform_Device_p->dev;
+
+    if (Data_p)
+        Data_p->PhysAddr = NULL;
+
+    return DevReference;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * device_rw API
+ *
+ * These functions can be used to transfer a single 32bit word or an array of
+ * 32bit words to or from a device.
+ * Endianness swapping is performed on the fly based on the configuration for
+ * this device.
+ *
+ */
+
+/*-----------------------------------------------------------------------------
+ * Device_Read32
+ */
+uint32_t
+Device_Read32(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset)
+{
+    uint32_t Value = 0;
+    Device_Read32Check(Device, ByteOffset, &Value);
+    return Value;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Read32Check
+ */
+int
+Device_Read32Check(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset,
+        uint32_t * const Value_p)
+{
+    Device_Admin_t * Device_p;
+    uint32_t Value = 0;
+
+    if (!HWPALLib_Device_Global.fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    Device_p = HWPALLib_Device2RecordPtr(Device);
+#else
+    Device_p = Device;
+#endif
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (!HWPALLib_IsValid(Device_p, ByteOffset))
+    {
+        LOG_CRIT("%s: invalid device (%p) or ByteOffset (%u)\n",
+                 __func__,
+                 Device,
+                 ByteOffset);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+#endif
+
+#ifdef HWPAL_ENABLE_HA_SIMULATION
+    if (Device_p->Flags & HWPAL_FLAG_HA)
+    {
+        // HA simulation mode
+        // disable access to PKA_MASTER_SEQ_CTRL
+        if (ByteOffset == 0x3FC8)
+        {
+            Value = 0;
+            goto HA_SKIP;
+        }
+    }
+#endif
+
+    {
+        unsigned int DeviceByteOffset = Device_p->FirstOfs + ByteOffset;
+
+        DeviceByteOffset = Device_RemapDeviceAddress(DeviceByteOffset);
+
+#ifdef HWPAL_DEVICE_DIRECT_MEMIO
+        Value = *(uint32_t *)(uintptr_t)(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                (DeviceByteOffset / 4));
+#else
+        Value = ioread32(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                (DeviceByteOffset / 4));
+#endif
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+        if (Device_p->Flags & HWPAL_FLAG_SWAP)
+            Value = Device_SwapEndian32(Value);
+#endif
+
+        smp_rmb();
+    }
+
+#ifdef HWPAL_ENABLE_HA_SIMULATION
+HA_SKIP:
+#endif
+
+#ifdef HWPAL_TRACE_DEVICE_READ
+    if (Device_p->Flags & HWPAL_FLAG_READ)
+    {
+        unsigned int DeviceByteOffset = Device_p->FirstOfs + ByteOffset;
+        unsigned int DeviceByteOffset2 =
+                Device_RemapDeviceAddress(DeviceByteOffset);
+
+        if (DeviceByteOffset2 != DeviceByteOffset)
+        {
+            DeviceByteOffset2 -= Device_p->FirstOfs;
+            Log_FormattedMessage("%s: 0x%x(was 0x%x) = 0x%08x (%s)\n",
+                                 __func__,
+                                 DeviceByteOffset2,
+                                 ByteOffset,
+                                 (unsigned int)Value,
+                                 Device_p->DevName);
+        }
+        else
+            Log_FormattedMessage("%s: 0x%x = 0x%08x (%s)\n",
+                                 __func__,
+                                 ByteOffset,
+                                 (unsigned int)Value,
+                                 Device_p->DevName);
+    }
+#endif /* HWPAL_TRACE_DEVICE_READ */
+
+    *Value_p = Value;
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Write32
+ */
+int
+Device_Write32(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset,
+        const uint32_t ValueIn)
+{
+    Device_Admin_t * Device_p;
+    uint32_t Value = ValueIn;
+
+    if (!HWPALLib_Device_Global.fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    Device_p = HWPALLib_Device2RecordPtr(Device);
+#else
+    Device_p = Device;
+#endif
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if (!HWPALLib_IsValid(Device_p, ByteOffset))
+    {
+        LOG_CRIT("%s: Invalid Device (%p) or ByteOffset (%u)\n",
+                 __func__,
+                 Device,
+                 ByteOffset);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+#endif
+
+#ifdef HWPAL_TRACE_DEVICE_WRITE
+    if (Device_p->Flags & HWPAL_FLAG_WRITE)
+        Log_FormattedMessage("%s: 0x%x = 0x%08x (%s)\n",
+                             __func__,
+                             ByteOffset,
+                             (unsigned int)Value,
+                             Device_p->DevName);
+#endif /* HWPAL_TRACE_DEVICE_WRITE*/
+
+#ifdef HWPAL_ENABLE_HA_SIMULATION
+    if (Device_p->Flags & HWPAL_FLAG_HA)
+    {
+        // HA simulation mode
+        // disable access to PKA_MASTER_SEQ_CTRL
+        if (ByteOffset == 0x3FC8)
+        {
+            LOG_CRIT("%s: Unexpected write to PKA_MASTER_SEQ_CTRL\n",
+                        __func__);
+            return 0;
+        }
+    }
+#endif
+
+    {
+        uint32_t DeviceByteOffset = Device_p->FirstOfs + ByteOffset;
+
+        DeviceByteOffset = Device_RemapDeviceAddress(DeviceByteOffset);
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+        if (Device_p->Flags & HWPAL_FLAG_SWAP)
+            Value = Device_SwapEndian32(Value);
+#endif
+
+#ifdef HWPAL_DEVICE_DIRECT_MEMIO
+        *(uint32_t *)(uintptr_t)(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                        (DeviceByteOffset / 4)) = Value;
+#else
+        iowrite32(Value,
+                  HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                  (DeviceByteOffset / 4));
+#endif
+
+        smp_wmb();
+    }
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Read32Array
+ */
+int
+Device_Read32Array(
+        const Device_Handle_t Device,
+        const unsigned int StartByteOffset, // read starts here, +4 increments
+        uint32_t * MemoryDst_p,             // writing starts here
+        const int Count)                    // number of uint32's to transfer
+{
+    Device_Admin_t * Device_p;
+    unsigned int DeviceByteOffset;
+
+    if (!HWPALLib_Device_Global.fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    Device_p = HWPALLib_Device2RecordPtr(Device);
+#else
+    Device_p = Device;
+#endif
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if ((Count <= 0) ||
+        MemoryDst_p == NULL ||
+        !HWPALLib_IsValid(Device_p, StartByteOffset) ||
+        !HWPALLib_IsValid(Device_p, StartByteOffset + (Count - 1) * 4))
+    {
+        LOG_CRIT("%s: Invalid Device (%p) or read area (%u-%u)\n",
+                 __func__,
+                 Device,
+                 StartByteOffset,
+                 (unsigned int)(StartByteOffset +
+                          (Count - 1) * sizeof(uint32_t)));
+         return DEVICE_RW_PARAM_ERROR;
+    }
+#endif
+
+#ifdef HWPAL_ENABLE_HA_SIMULATION
+    if (Device_p->Flags & HWPAL_FLAG_HA)
+    {
+        // HA simulation mode
+        // disable access to PKA_MASTER_SEQ_CTRL
+        return 0;
+    }
+#endif
+
+    DeviceByteOffset = Device_p->FirstOfs + StartByteOffset;
+
+    {
+        unsigned int RemappedOffset;
+        uint32_t Value;
+        int i;
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+        bool fSwap = false;
+
+        if (Device_p->Flags & HWPAL_FLAG_SWAP)
+            fSwap = true;
+#endif
+        for (i = 0; i < Count; i++)
+        {
+            RemappedOffset = Device_RemapDeviceAddress(DeviceByteOffset);
+
+#ifdef HWPAL_DEVICE_DIRECT_MEMIO
+            Value =
+               *(uint32_t*)(uintptr_t)(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                (RemappedOffset / 4));
+#else
+            Value = ioread32(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                (RemappedOffset / 4));
+#endif
+
+            smp_rmb();
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+            // swap endianness if required
+            if (fSwap)
+                Value = Device_SwapEndian32(Value);
+#endif
+
+            MemoryDst_p[i] = Value;
+            DeviceByteOffset +=  4;
+        } // for
+    }
+
+#ifdef HWPAL_TRACE_DEVICE_READ
+    if (Device_p->Flags & HWPAL_FLAG_READ)
+    {
+        HWPAL_Hexdump(
+                      __func__,
+                      Device_p->DevName,
+                      Device_p->FirstOfs + StartByteOffset,
+                      MemoryDst_p,
+                      Count,
+                      false);     // already swapped during read above
+    }
+#endif /* HWPAL_TRACE_DEVICE_READ */
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Device_Write32Array
+ */
+int
+Device_Write32Array(
+        const Device_Handle_t Device,
+        const unsigned int StartByteOffset, // write starts here, +4 increments
+        const uint32_t * MemorySrc_p,       // reading starts here
+        const int Count)                    // number of uint32's to transfer
+{
+    Device_Admin_t * Device_p;
+    unsigned int DeviceByteOffset;
+
+    if (MemorySrc_p == NULL || Count <= 0)
+        return DEVICE_RW_PARAM_ERROR;
+
+    if (!HWPALLib_Device_Global.fInitialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return DEVICE_RW_PARAM_ERROR;
+    }
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    Device_p = HWPALLib_Device2RecordPtr(Device);
+#else
+    Device_p = Device;
+#endif
+
+#ifdef HWPAL_STRICT_ARGS_CHECK
+    if ((Count <= 0) ||
+        MemorySrc_p == NULL ||
+        !HWPALLib_IsValid(Device_p, StartByteOffset) ||
+        !HWPALLib_IsValid(Device_p, StartByteOffset + (Count - 1) * 4))
+    {
+        LOG_CRIT("%s: Invalid Device (%p) or write area (%u-%u)\n",
+                 __func__,
+                 Device,
+                 StartByteOffset,
+                 (unsigned int)(StartByteOffset + (Count - 1) *
+                                                 sizeof(uint32_t)));
+        return DEVICE_RW_PARAM_ERROR;
+    }
+#endif
+
+    DeviceByteOffset = Device_p->FirstOfs + StartByteOffset;
+
+#ifdef HWPAL_ENABLE_HA_SIMULATION
+    if (Device_p->Flags & HWPAL_FLAG_HA)
+    {
+        // HA simulation mode
+        // disable access to PKA_MASTER_SEQ_CTRL
+        return 0;
+    }
+#endif
+
+#ifdef HWPAL_TRACE_DEVICE_WRITE
+    if (Device_p->Flags & HWPAL_FLAG_WRITE)
+    {
+        bool fSwap = false;
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+        if (Device_p->Flags & HWPAL_FLAG_SWAP)
+            fSwap = true;
+#endif
+
+        HWPAL_Hexdump(
+                      __func__,
+                      Device_p->DevName,
+                      DeviceByteOffset,
+                      MemorySrc_p,
+                      Count,
+                      fSwap);
+    }
+#endif /* HWPAL_TRACE_DEVICE_WRITE */
+
+    {
+        unsigned int RemappedOffset;
+        uint32_t Value;
+        int i;
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+        bool fSwap = false;
+
+        if (Device_p->Flags & HWPAL_FLAG_SWAP)
+            fSwap = true;
+#endif
+
+        for (i = 0; i < Count; i++)
+        {
+            RemappedOffset = Device_RemapDeviceAddress(DeviceByteOffset);
+            Value = MemorySrc_p[i];
+
+#ifdef HWPAL_DEVICE_ENABLE_SWAP
+            if (fSwap)
+                Value = Device_SwapEndian32(Value);
+#endif
+
+#ifdef HWPAL_DEVICE_DIRECT_MEMIO
+            *(uint32_t*)(uintptr_t)(HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                            (RemappedOffset / 4)) = Value;
+#else
+            iowrite32(Value, HWPALLib_Device_Global.Platform.MappedBaseAddr_p +
+                                                (RemappedOffset / 4));
+#endif
+
+            smp_wmb();
+
+            DeviceByteOffset += 4;
+        } // for
+    }
+
+    return 0;
+}
+
+
+/* end of file device_lkm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/lkm.c b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/lkm.c
new file mode 100644
index 0000000..8045d59
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/device/lkm/of/lkm.c
@@ -0,0 +1,444 @@
+/* lkm.c
+ *
+ * Linux Kernel Module implementation for Platform device drivers
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Linux Kernel Module interface
+#include "lkm.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_lkm.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t, NULL, inline, bool,
+                                    // IDENTIFIER_NOT_USED
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"                   // memcmp
+
+// Logging API
+#undef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX  LKM_LOG_SEVERITY
+#include "log.h"                    // LOG_*
+
+// Linux Kernel API
+#include <linux/types.h>            // phys_addr_t, resource_size_t
+#include <linux/version.h>          // LINUX_VERSION_CODE, KERNEL_VERSION
+#include <linux/device.h>           // struct device
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>  // platform_*,
+#include <linux/of_platform.h>      // of_*,
+#include <asm/io.h>                 // ioremap, iounmap
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/moduleparam.h>
+#include <linux/clk.h>              // clk_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// LKM PCI implementation administration data
+typedef struct
+{
+    // declarations native to Linux kernel
+    struct platform_device * Platform_Device_p;
+
+    // virtual address returned by ioremap()
+    uint32_t __iomem * MappedBaseAddr_p;
+
+    // physical address passed to ioremap()
+    phys_addr_t PhysBaseAddr;
+
+    // Platform device driver data
+    struct platform_driver Platform_Driver;
+
+    // Device resource (IO space) identifier
+    int ResId;
+
+    // Device resource size in bytes
+    resource_size_t ResByteCount;
+
+    // Device virtual IRQ number
+    int VirtIrqNr [LKM_PLATFORM_IRQ_COUNT];
+
+    bool fRetainMap;
+
+    // Initialization flag, true - initialized, otherwise - false
+    bool fInitialized;
+
+} LKM_Admin_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static struct clk *gateclk;
+
+static const struct of_device_id LKM_DT_IDTable[] =
+{
+    { .compatible = LKM_PLATFORM_DEVICE_NAME, },
+    { },
+};
+
+// LKM administration data
+static LKM_Admin_t LKM_Admin;
+
+
+/*----------------------------------------------------------------------------
+ * LKM_Probe
+ */
+static int
+LKM_Probe(
+        struct platform_device * Platform_Device_p)
+{
+    int i;
+    LKM_Admin_t * p = &LKM_Admin;
+    struct resource * rsc_p = NULL;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: entered\n", __func__);
+
+    if (Platform_Device_p == NULL)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX
+                 "%s: failed, missing platform device\n",
+                 __func__);
+        return -ENODEV;
+    }
+
+    if (of_find_compatible_node(NULL, NULL, LKM_PLATFORM_DEVICE_NAME))
+    {
+        LOG_INFO(LKM_LOG_PREFIX
+                 "%s: found requested device %s\n",
+                 __func__,
+                 LKM_PLATFORM_DEVICE_NAME);
+    }
+    else
+    {
+        LOG_CRIT(LKM_LOG_PREFIX
+                 "%s: device %s not supported\n",
+                 __func__,
+                 LKM_PLATFORM_DEVICE_NAME);
+        return -ENODEV;
+    }
+
+    // remember the device reference
+    p->Platform_Device_p = Platform_Device_p;
+
+    if (p->fRetainMap)
+    {
+        // get platform device physical address
+        // Exported under GPL
+        rsc_p = platform_get_resource(Platform_Device_p,
+                                      IORESOURCE_MEM,
+                                      p->ResId);
+
+        // device tree specific for this OF device
+        // only 32-bit physical addresses are supported
+        if(rsc_p)
+        {
+            LOG_INFO(LKM_LOG_PREFIX
+                     "%s: mem start=%08x, end=%08x, flags=%08x\n",
+                     __func__,
+                     (unsigned int)rsc_p->start,
+                     (unsigned int)rsc_p->end,
+                     (unsigned int)rsc_p->flags);
+        }
+        else
+        {
+            LOG_CRIT(LKM_LOG_PREFIX
+                     "%s: memory resource id %d not found\n",
+                     __func__,
+                     p->ResId);
+            return -ENODEV;
+        }
+
+        p->PhysBaseAddr      = rsc_p->start;
+        p->ResByteCount      = rsc_p->end - rsc_p->start + 1;
+
+        // now map the chip into kernel memory
+        // so we can access the EIP static resources
+
+        // note: ioremap is uncached by default
+        p->MappedBaseAddr_p = ioremap(p->PhysBaseAddr, p->ResByteCount);
+        if (p->MappedBaseAddr_p == NULL)
+        {
+            LOG_CRIT(LKM_LOG_PREFIX
+                     "%s: failed to ioremap platform driver %s, "
+                     "resource id %d, phys addr 0x%p, size %ul\n",
+                     __func__,
+                     p->Platform_Driver.driver.name,
+                     p->ResId,
+                     (void*)p->PhysBaseAddr,
+                     (unsigned int)p->ResByteCount);
+            return -ENODEV;
+        }
+
+        LOG_INFO(LKM_LOG_PREFIX
+                 "%s: Mapped platform driver %s addr %p, phys addr 0x%p, "
+                 "sizeof(resource_size_t)=%d\n resource id=%d, size=%ul\n",
+                 __func__,
+                 p->Platform_Driver.driver.name,
+                 p->MappedBaseAddr_p,
+                 (void*)p->PhysBaseAddr,
+                 (int)sizeof(resource_size_t),
+                 p->ResId,
+                 (unsigned int)p->ResByteCount);
+    }
+
+    // Optional device clock control functionality,
+    // only required when the device clock needs to be enabled via the kernel
+    gateclk = clk_get(&Platform_Device_p->dev, NULL);
+    if (!IS_ERR(gateclk))
+    {
+        // Exported under GPL
+        clk_prepare_enable(gateclk);
+        LOG_INFO("%s: clk_prepare_enable() successful\n", __func__);
+    }
+    else
+    {
+        // Not all devices support it
+        LOG_INFO("%s: clk_get() could not obtain clock\n", __func__);
+    }
+
+    for (i = 0; i < LKM_PLATFORM_IRQ_COUNT; i++)
+    {
+        int IrqNr, IrqIndex;
+
+        IrqIndex = LKM_PLATFORM_IRQ_COUNT > 1 ? i : LKM_PLATFORM_IRQ_IDX;
+
+        // Exported under GPL
+        IrqNr = platform_get_irq(Platform_Device_p, IrqIndex);
+        if (IrqNr < 0)
+        {
+            LOG_INFO(LKM_LOG_PREFIX "%s: failed to get IRQ for index %d\n",
+                     __func__,
+                     IrqIndex);
+            return -ENODEV;
+        }
+        else
+            p->VirtIrqNr[i] = IrqNr;
+    }
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: left\n", __func__);
+
+    // return 0 to indicate "we decided to take ownership"
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * LKM_Remove
+ */
+static int
+LKM_Remove(
+        struct platform_device * Platform_Device_p)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: entered\n", __func__);
+
+    if (p->Platform_Device_p != Platform_Device_p)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX
+                 "%s: failed, missing or wrong platform device\n",
+                 __func__);
+        return -ENODEV;
+    }
+
+    LOG_INFO(LKM_LOG_PREFIX
+             "%s: mapped base addr=%p\n", __func__, p->MappedBaseAddr_p);
+
+    // Optional device clock control functionality
+    if (!IS_ERR(gateclk))
+    {
+        // Exported under GPL
+        clk_disable_unprepare(gateclk);
+        clk_put(gateclk);
+    }
+
+    if (p->MappedBaseAddr_p && p->fRetainMap)
+    {
+        iounmap(p->MappedBaseAddr_p);
+        p->MappedBaseAddr_p = NULL;
+    }
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: left\n", __func__);
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_Init
+ */
+int
+LKM_Init(
+        LKM_Init_t * const InitData_p)
+{
+    int Status;
+    LKM_Admin_t * p = &LKM_Admin;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: entered\n", __func__);
+
+    // Check input parameters
+    if(InitData_p == NULL)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX "%s: failed, missing init data\n", __func__);
+        return -1;
+    }
+
+    if (p->fInitialized)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX "%s: failed, already initialized\n", __func__);
+        return -2;
+    }
+
+    // Fill in PCI device driver data
+    p->fRetainMap                    = InitData_p->fRetainMap;
+    p->ResId                         = InitData_p->ResId; // not used
+
+    p->Platform_Driver.probe         = LKM_Probe;
+    p->Platform_Driver.remove        = LKM_Remove;
+
+    p->Platform_Driver.driver.name            = InitData_p->DriverName_p;
+    p->Platform_Driver.driver.owner           = THIS_MODULE;
+    p->Platform_Driver.driver.pm              = InitData_p->PM_p;
+    p->Platform_Driver.driver.of_match_table  = LKM_DT_IDTable;
+
+    // Exported under GPL
+    Status = platform_driver_register(&p->Platform_Driver);
+    if (Status < 0)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX
+                 "%s: failed to register platform device driver\n",
+                 __func__);
+        return -3;
+    }
+
+    if (p->Platform_Device_p == NULL)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX "%s: failed, no device detected\n", __func__);
+        platform_driver_unregister(&p->Platform_Driver);
+        return -4;
+    }
+
+    // if provided, CustomInitData_p points to an "int"
+    // we return a pointer to the arrays of irq numbers
+    InitData_p->CustomInitData_p = p->VirtIrqNr;
+
+    p->fInitialized = true;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: left\n", __func__);
+
+    return 0; // success
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_Uninit
+ */
+void
+LKM_Uninit(void)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: entered\n", __func__);
+
+    if (!p->fInitialized)
+    {
+        LOG_CRIT(LKM_LOG_PREFIX "%s: failed, not initialized yet\n", __func__);
+        return;
+    }
+
+    LOG_INFO(LKM_LOG_PREFIX
+             "%s: calling platform_driver_unregister\n",
+             __func__);
+
+    platform_driver_unregister(&p->Platform_Driver);
+
+    ZEROINIT(LKM_Admin); //p->fInitialized = false;
+
+    LOG_INFO(LKM_LOG_PREFIX "%s: left\n", __func__);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_DeviceGeneric_Get
+ */
+void *
+LKM_DeviceGeneric_Get(void)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    return &p->Platform_Device_p->dev;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_DeviceSpecific_Get
+ */
+void *
+LKM_DeviceSpecific_Get(void)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    return p->Platform_Device_p;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_PhysBaseAddr_Get
+ */
+void *
+LKM_PhysBaseAddr_Get(void)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    return (void*)p->PhysBaseAddr;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_MappedBaseAddr_Get
+ */
+void __iomem *
+LKM_MappedBaseAddr_Get(void)
+{
+    LKM_Admin_t * p = &LKM_Admin;
+
+    return p->MappedBaseAddr_p;
+}
+
+
+/* end of file lkm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/basic_defs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/basic_defs.h
new file mode 100644
index 0000000..c031bcd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/basic_defs.h
@@ -0,0 +1,200 @@
+/* basic_defs.h
+ *
+ * Driver Framework v4, Basic Definitions.
+ *
+ * This file provides a number of basic definitions and can be customized for
+ * any compiler.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_BASIC_DEFS_H
+#define INCLUDE_GUARD_BASIC_DEFS_H
+
+
+/* ============ Compiler-based Configuration ============ */
+
+//#if __STDC_VERSION__ < 199901L
+//#error "BasicDefs: C standards older than C99 not supported"
+//#endif
+
+#ifdef _MSC_VER
+#define BASICDEFS_COMPILER_MICROSOFT_V1
+#define BASICDEFS_TYPES_V1
+#define BASICDEFS_BOOL_V1
+// Microsoft compiler only supports "inline" in C++ mode and
+// expects __inline in C mode
+#define BASICDEFS_INLINE_V1
+#endif
+
+#ifdef linux
+#ifdef MODULE
+// kernel loadable module
+#define BASICDEFS_COMPILER_LINUX_V1
+#define BASICDEFS_INLINE_BUILTIN
+#include <linux/types.h>
+#else
+// user mode
+#define BASICDEFS_COMPILER_LINUX_V1
+#define BASICDEFS_TYPES_STDINT
+#define BASICDEFS_BOOL_V1
+#define BASICDEFS_INLINE_BUILTIN
+#endif
+#endif
+
+#ifdef __STDC_VERSION__
+#if __STDC_VERSION__ >= 199901L
+#define BASICDEFS_TYPES_STDINT
+#define BASICDEFS_BOOL_V1
+#define BASICDEFS_INLINE_BUILTIN
+#endif
+#endif
+
+#ifdef __CYGWIN__
+#define BASICDEFS_COMPILER_CYGWIN_V1
+#define BASICDEFS_TYPES_STDINT
+#define BASICDEFS_BOOL_V1
+#define BASICDEFS_INLINE_BUILTIN
+#endif
+
+/* ============ Basic Types ============ */
+
+#ifdef BASICDEFS_TYPES_STDINT
+// ISO-C99
+#include <stdint.h>
+#endif
+
+#ifdef BASICDEFS_TYPES_V1
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+#endif
+
+/* ============ Boolean type ============ */
+
+#ifdef BASICDEFS_BOOL_V1
+// ISO-C99
+#include <stdbool.h>
+#endif
+
+/* ============ NULL ============ */
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* ============ MIN, MAX ============ */
+
+// warning for side-effects on the following two macros since the arguments
+// are evaluated twice changing this to inline functions is problematic
+// because of type incompatibilities
+#define MIN(_x, _y) ((_x) < (_y) ? (_x) : (_y))
+#define MAX(_x, _y) ((_x) > (_y) ? (_x) : (_y))
+
+/* ============ BIT_n ============ */
+
+// using postfix "U" to be compatible with uint32
+// ("UL" is not needed and gives lint warning)
+#define BIT_0   0x00000001U
+#define BIT_1   0x00000002U
+#define BIT_2   0x00000004U
+#define BIT_3   0x00000008U
+#define BIT_4   0x00000010U
+#define BIT_5   0x00000020U
+#define BIT_6   0x00000040U
+#define BIT_7   0x00000080U
+#define BIT_8   0x00000100U
+#define BIT_9   0x00000200U
+#define BIT_10  0x00000400U
+#define BIT_11  0x00000800U
+#define BIT_12  0x00001000U
+#define BIT_13  0x00002000U
+#define BIT_14  0x00004000U
+#define BIT_15  0x00008000U
+#define BIT_16  0x00010000U
+#define BIT_17  0x00020000U
+#define BIT_18  0x00040000U
+#define BIT_19  0x00080000U
+#define BIT_20  0x00100000U
+#define BIT_21  0x00200000U
+#define BIT_22  0x00400000U
+#define BIT_23  0x00800000U
+#define BIT_24  0x01000000U
+#define BIT_25  0x02000000U
+#define BIT_26  0x04000000U
+#define BIT_27  0x08000000U
+#define BIT_28  0x10000000U
+#define BIT_29  0x20000000U
+#define BIT_30  0x40000000U
+#define BIT_31  0x80000000U
+
+/* ============ MASK_n_BITS ============ */
+
+#define MASK_1_BIT      (BIT_1 - 1)
+#define MASK_2_BITS     (BIT_2 - 1)
+#define MASK_3_BITS     (BIT_3 - 1)
+#define MASK_4_BITS     (BIT_4 - 1)
+#define MASK_5_BITS     (BIT_5 - 1)
+#define MASK_6_BITS     (BIT_6 - 1)
+#define MASK_7_BITS     (BIT_7 - 1)
+#define MASK_8_BITS     (BIT_8 - 1)
+#define MASK_9_BITS     (BIT_9 - 1)
+#define MASK_10_BITS    (BIT_10 - 1)
+#define MASK_11_BITS    (BIT_11 - 1)
+#define MASK_12_BITS    (BIT_12 - 1)
+#define MASK_13_BITS    (BIT_13 - 1)
+#define MASK_14_BITS    (BIT_14 - 1)
+#define MASK_15_BITS    (BIT_15 - 1)
+#define MASK_16_BITS    (BIT_16 - 1)
+#define MASK_17_BITS    (BIT_17 - 1)
+#define MASK_18_BITS    (BIT_18 - 1)
+#define MASK_19_BITS    (BIT_19 - 1)
+#define MASK_20_BITS    (BIT_20 - 1)
+#define MASK_21_BITS    (BIT_21 - 1)
+#define MASK_22_BITS    (BIT_22 - 1)
+#define MASK_23_BITS    (BIT_23 - 1)
+#define MASK_24_BITS    (BIT_24 - 1)
+#define MASK_25_BITS    (BIT_25 - 1)
+#define MASK_26_BITS    (BIT_26 - 1)
+#define MASK_27_BITS    (BIT_27 - 1)
+#define MASK_28_BITS    (BIT_28 - 1)
+#define MASK_29_BITS    (BIT_29 - 1)
+#define MASK_30_BITS    (BIT_30 - 1)
+#define MASK_31_BITS    (BIT_31 - 1)
+
+#define MASK_N_BITS(start, end) ((-1U >> (31 - (end))) & ~((1U << (start)) - 1))
+
+/* ============ EXTRACT_BIT(S) ============ */
+#define EXTRACT_BIT(bit, input)         (((input) >> (bit)) & 1U)
+#define EXTRACT_BITS(start, end, input) (((input) >> (start)) & MASK_N_BITS(0, (end) - (start)))
+
+/* ============ IDENTIFIER_NOT_USED ============ */
+
+#define IDENTIFIER_NOT_USED(_v)   (void)(_v)
+
+/* ============ inline ============ */
+
+#ifdef BASICDEFS_INLINE_V1
+#define inline __inline
+#endif
+
+
+#endif /* Inclusion Guard */
+
+
+/* end of file basic_defs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter.h
new file mode 100644
index 0000000..d363dd3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter.h
@@ -0,0 +1,557 @@
+/* cs_adapter.h
+ *
+ * Configuration Settings for the SLAD Adapter Combined module.
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+// we accept a few settings from the top-level configuration file
+#include "cs_driver.h"
+
+// Adapter extensions
+#include "cs_adapter_ext.h"
+
+// DDK configuration
+#include "cs_ddk197.h"
+
+/****************************************************************************
+ * Adapter Global configuration parameters
+ */
+
+// log level for the entire adapter (for now)
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LOG_SEVERITY_MAX
+#ifdef DRIVER_PERFORMANCE
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_CRITICAL
+#else
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_WARN
+#endif
+#endif
+
+// Do a register dump after ring initialization
+//#define ADAPTER_EIP202_ADD_INIT_DIAGNOSTICS
+
+
+#define ADAPTER_VERSION_STRING DDK_EIP197_VERSION_STRING
+
+#ifdef DRIVER_NAME
+#define ADAPTER_DRIVER_NAME     DRIVER_NAME
+#else
+#define ADAPTER_DRIVER_NAME     "Security"
+#endif
+
+#ifdef DRIVER_LICENSE
+#define ADAPTER_LICENSE         DRIVER_LICENSE
+#else
+#define ADAPTER_LICENSE         "GPL"
+#endif
+
+// Allow longer firmware path names.
+#define ADAPTER_FIRMWARE_NAMELEN_MAX  256
+
+// PCI configuration value: Cache Line Size, in 32bit words
+// Advised value: 1
+#define ADAPTER_PCICONFIG_CACHELINESIZE   1
+
+// PCI configuration value: Master Latency Timer, in PCI bus clocks
+// Advised value: 0xf8
+#define ADAPTER_PCICONFIG_MASTERLATENCYTIMER 0xf8
+
+// filter for printing interrupts
+#ifdef DRIVER_INTERRUPTS
+#define ADAPTER_INTERRUPTS_TRACEFILTER 0x00
+#else
+#define ADAPTER_INTERRUPTS_TRACEFILTER 0x00
+#endif
+
+// Is host platform 64-bit?
+#ifdef DRIVER_64BIT_HOST
+#define ADAPTER_64BIT_HOST
+#endif  // DRIVER_64BIT_HOST
+
+// Is device 64-bit?
+#ifdef DRIVER_64BIT_DEVICE
+#define ADAPTER_64BIT_DEVICE
+#endif  // DRIVER_64BIT_DEVICE
+
+// Maximum number of descriptors that can be submitted in one go.
+#ifdef DRIVER_MAX_PECLOGICDESCR
+#define ADAPTER_MAX_PECLOGICDESCR       DRIVER_MAX_PECLOGICDESCR
+#else
+#define ADAPTER_MAX_PECLOGICDESCR       10
+#endif
+
+// switch to remove support for bounce buffers
+#ifndef DRIVER_BOUNCEBUFFERS
+#define ADAPTER_REMOVE_BOUNCEBUFFERS
+#endif
+
+// Fix up the packet automatically. (inserting appended fields into header)
+#define ADAPTER_AUTO_FIXUP
+
+#define ADAPTER_GLOBAL_DEVICE_NAME          "EIP197_GLOBAL"
+
+#define ADAPTER_GLOBAL_DBG_STATISTICS
+
+// the number of packets in the result ring before the related interrupt
+// is activated. This reduces the number of interrupts and allows the
+// host to get many results in one call to PEC_Packet_Get.
+#ifdef DRIVER_INTERRUPT_COALESCING
+#define ADAPTER_DESCRIPTORDONECOUNT  4
+#else
+#define ADAPTER_DESCRIPTORDONECOUNT  1
+#endif
+
+// maximum delay until activating an interrupt
+// after writing a result descriptor to the result ring
+// desired maximum time: T in seconds
+// calculate configuration value N as follows:
+//   N = T (seconds) * Engine frequency (Hz) / 1024
+// example: T = 100 microseconds,
+//          Engine frequency = 100 MHz
+// N = (1 / 10 000) sec * 100 000 000 Hz / 1024 ~= 10
+#ifdef DRIVER_INTERRUPT_COALESCING
+#define ADAPTER_DESCRIPTORDONETIMEOUT  20
+#else
+#define ADAPTER_DESCRIPTORDONETIMEOUT  0
+#endif
+
+#ifdef DRIVER_DMARESOURCE_BANKS_ENABLE
+#define ADAPTER_DMARESOURCE_BANKS_ENABLE
+#endif
+
+// DMA buffer allocation alignment
+#ifdef DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#define ADAPTER_PCL_DMA_ALIGNMENT_BYTE_COUNT DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#endif
+
+// Define if the hardware does not use large transform records
+#ifndef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+#define ADAPTER_USE_LARGE_TRANSFORM_DISABLE
+#endif
+
+
+/****************************************************************************
+ * Adapter PEC configuration parameters
+ */
+
+// enable debug checks
+#ifndef DRIVER_PERFORMANCE
+#define ADAPTER_PEC_DBG
+#define ADAPTER_PEC_STRICT_ARGS
+#endif
+
+// Maximum number of supported Packet Engine devices
+#ifdef DRIVER_MAX_NOF_RING_TO_USE
+#define ADAPTER_PEC_DEVICE_COUNT       DRIVER_MAX_NOF_RING_TO_USE
+#else
+#define ADAPTER_PEC_DEVICE_COUNT       1
+#endif
+
+#define ADAPTER_GLOBAL_EIP97_NOF_PES DRIVER_MAX_NOF_PE_TO_USE
+#define ADAPTER_GLOBAL_EIP97_RINGMASK ((1 << ADAPTER_PEC_DEVICE_COUNT) - 1)
+
+// the number of SA records the driver can register
+// if State record or ARC4 State record are used together with SA record
+// then this number should be increased by factor of 2 or 3 respectively
+#ifndef DRIVER_PEC_MAX_SAS
+#define ADAPTER_PEC_MAX_SAS         60
+#else
+#define ADAPTER_PEC_MAX_SAS         DRIVER_PEC_MAX_SAS
+#endif
+
+// the number of packets the driver can buffer either in its input buffer
+// a.k.a. Packet Descriptor Ring (PDR) or its output buffer
+// a.k.a. Result Descriptor Ring (RDR)
+#ifndef DRIVER_PEC_MAX_PACKETS
+#define ADAPTER_PEC_MAX_PACKETS     10
+#else
+#define ADAPTER_PEC_MAX_PACKETS     DRIVER_PEC_MAX_PACKETS
+#endif
+
+// one for commands, the other for results
+#ifdef DRIVER_PE_ARM_SEPARATE
+#define ADAPTER_PEC_SEPARATE_RINGS
+#endif
+
+#ifdef ADAPTER_MAX_PECLOGICDESCR
+#define ADAPTER_PEC_MAX_LOGICDESCR  ADAPTER_MAX_PECLOGICDESCR
+#endif
+
+#if ADAPTER_PEC_MAX_LOGICDESCR > ADAPTER_PEC_MAX_PACKETS
+#error "Error: ADAPTER_PEC_MAX_LOGICDESCR > ADAPTER_PEC_MAX_PACKETS"
+#endif
+
+#ifndef DRIVER_BOUNCEBUFFERS
+#define ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+#endif
+
+#ifdef DRIVER_SCATTERGATHER
+
+#define ADAPTER_PEC_ENABLE_SCATTERGATHER
+
+// the maximum number of fragments per packet
+#define ADAPTER_PEC_MAX_FRAGMENTS_PER_PACKET    4
+
+// the maximum number of descriptors in the gather and scatter rings
+#define ADAPTER_PEC_SC_RING_MAX_DESCRIPTORS \
+        (ADAPTER_PEC_MAX_FRAGMENTS_PER_PACKET * ADAPTER_PEC_MAX_PACKETS)
+
+#endif /* scatter/gather */
+
+#ifdef DRIVER_INTERRUPTS
+#define ADAPTER_PEC_INTERRUPTS_ENABLE
+#define ADAPTER_EIP74_INTERRUPTS_ENABLE
+#define ADAPTER_EIP74_ERR_IRQ IRQ_DRBG_ERR // DRBG error interrupt
+#define ADAPTER_EIP74_RES_IRQ IRQ_DRBG_RES // DRBG reseed early interrupt
+#endif
+
+// enable for big-endian CPU
+#ifdef DRIVER_SWAPENDIAN
+#define ADAPTER_PEC_ARMRING_ENABLE_SWAP
+#endif //DRIVER_SWAPENDIAN
+
+#ifdef DRIVER_PEC_BANK_RING
+#define ADAPTER_PEC_BANK_RING                   DRIVER_PEC_BANK_RING
+#endif
+
+#ifdef DRIVER_PEC_BANK_PACKET
+#define ADAPTER_PEC_BANK_PACKET                 DRIVER_PEC_BANK_PACKET
+#endif
+
+#ifdef DRIVER_PEC_BANK_TOKEN
+#define ADAPTER_PEC_BANK_TOKEN                  DRIVER_PEC_BANK_TOKEN
+#endif
+
+// DMA resource bank for SLAD PEC Adapter, used for bouncing SA buffers
+#ifdef DRIVER_PEC_BANK_SA
+#define ADAPTER_PEC_BANK_SA                     DRIVER_PEC_BANK_SA
+#endif
+
+
+/****************************************************************************
+ * Adapter Classification (Global Control) configuration parameters
+ */
+
+#define ADAPTER_CS_GLOBAL_DEVICE_NAME       ADAPTER_GLOBAL_DEVICE_NAME
+
+// Maximum number of EIP-207c Classification Engines that can be used
+#ifdef DRIVER_CS_MAX_NOF_CE_TO_USE
+#define ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE DRIVER_CS_MAX_NOF_CE_TO_USE
+#else
+#define ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE            1
+#endif
+
+// Enable per-transform redirect for all interfaces
+#define ADAPTER_CS_GLOBAL_TRANSFORM_REDIRECT_ENABLE 0xffff
+
+// Maximum supported number of flow hash tables
+#ifdef DRIVER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE  \
+                        DRIVER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#else
+#define ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE     1
+#endif
+
+
+/****************************************************************************
+ * Adapter PCL (Flow Control) configuration parameters
+ */
+
+#define ADAPTER_PCL_DEVICE_NAME             ADAPTER_GLOBAL_DEVICE_NAME
+
+// Flow hash table size.
+#ifdef DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT
+#define ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT
+#else
+#define ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT 1024
+#endif
+
+// Number of overflow buckets associated with hash table
+#ifdef DRIVER_PCL_FLOW_HASH_OVERFLOW_COUNT
+#define ADAPTER_PCL_FLOW_HASH_OVERFLOW_COUNT    \
+                DRIVER_PCL_FLOW_HASH_OVERFLOW_COUNT
+#endif
+
+#ifdef DRIVER_PCL_FLOW_REMOVE_MAX_TRIES
+#define ADAPTER_PCL_FLOW_REMOVE_MAX_TRIES     DRIVER_PCL_FLOW_REMOVE_MAX_TRIES
+#endif
+
+#ifdef DRIVER_PCL_FLOW_REMOVE_DELAY_MS
+#define ADAPTER_PCL_FLOW_REMOVE_DELAY         DRIVER_PCL_FLOW_REMOVE_DELAY_MS
+#endif
+
+#ifdef DRIVER_PCL_MAX_FLUE_DEVICES
+#define ADAPTER_PCL_MAX_FLUE_DEVICES          DRIVER_PCL_MAX_FLUE_DEVICES
+#endif
+
+// enable for big-endian CPU
+#ifdef DRIVER_SWAPENDIAN
+#define ADAPTER_PCL_ENABLE_SWAP
+#endif //DRIVER_SWAPENDIAN
+
+#define ADAPTER_PCL_ENABLE
+
+#ifdef DRIVER_DMARESOURCE_BANKS_ENABLE
+#define ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+#endif // DRIVER_DMARESOURCE_BANKS_ENABLE
+
+// DMA resource bank for PCL transform records
+#ifdef DRIVER_PCL_BANK_TRANSFORM
+#define ADAPTER_PCL_BANK_TRANSFORM              DRIVER_PCL_BANK_TRANSFORM
+#endif
+
+// DMA resource bank for flow records
+#ifdef DRIVER_PCL_BANK_FLOW
+#define ADAPTER_PCL_BANK_FLOW                   DRIVER_PCL_BANK_FLOW
+#endif
+
+// DMA resource bank for flow table (also for overflow hash buckets)
+#ifdef DRIVER_PCL_BANK_FLOWTABLE
+#define ADAPTER_PCL_BANK_FLOWTABLE              DRIVER_PCL_BANK_FLOWTABLE
+#endif
+
+#ifdef DRIVER_LIST_PCL_OFFSET
+#define ADAPTER_PCL_LIST_ID_OFFSET              DRIVER_LIST_PCL_OFFSET
+#endif
+
+// Define if the hardware does not (need to) use large transform records
+#ifdef ADAPTER_USE_LARGE_TRANSFORM_DISABLE
+#define ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+#define ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
+#endif
+
+
+/****************************************************************************
+ * Adapter EIP-202 configuration parameters
+ */
+
+// enable debug checks
+#ifndef DRIVER_PERFORMANCE
+#define ADAPTER_EIP202_STRICT_ARGS
+#endif
+
+#ifdef ADAPTER_DRIVER_NAME
+#define ADAPTER_EIP202_DRIVER_NAME ADAPTER_DRIVER_NAME
+#endif
+
+#ifdef ADAPTER_GLOBAL_DEVICE_NAME
+#define ADAPTER_EIP202_GLOBAL_DEVICE_NAME    ADAPTER_GLOBAL_DEVICE_NAME
+#endif
+
+#ifdef DRIVER_64BIT_DEVICE
+#define ADAPTER_EIP202_64BIT_DEVICE
+#endif
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+#define ADAPTER_EIP202_ENABLE_SCATTERGATHER
+#endif
+
+#ifdef ADAPTER_PEC_SEPARATE_RINGS
+#define ADAPTER_EIP202_SEPARATE_RINGS
+#endif
+
+#ifdef ADAPTER_PEC_MAX_PACKETS
+#define ADAPTER_EIP202_MAX_PACKETS      ADAPTER_PEC_MAX_PACKETS
+#endif
+
+#ifdef ADAPTER_DESCRIPTORDONECOUNT
+#define ADAPTER_EIP202_DESCRIPTORDONECOUNT  ADAPTER_DESCRIPTORDONECOUNT
+#endif
+
+#ifdef ADAPTER_DESCRIPTORDONETIMEOUT
+#define ADAPTER_EIP202_DESCRIPTORDONETIMEOUT  ADAPTER_DESCRIPTORDONETIMEOUT
+#endif
+
+#ifdef ADAPTER_PEC_MAX_LOGICDESCR
+#define ADAPTER_EIP202_MAX_LOGICDESCR   ADAPTER_PEC_MAX_LOGICDESCR
+#endif
+
+// switch to remove support for bounce buffers
+#ifndef DRIVER_BOUNCEBUFFERS
+#define ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
+#endif
+
+// descriptor spacing in words, allowing cache line alignment
+// ring memory start alignment will use same value
+#define ADAPTER_SYSTEM_DCACHE_LINE_SIZE_BYTES  32
+#define ADAPTER_EIP97_DESCRIPTORSPACING_WORDS \
+                (ADAPTER_SYSTEM_DCACHE_LINE_SIZE_BYTES / 4)
+
+// Threshold for DMA input (read) and output (write)
+// The transfer is initiated when the number of positions in
+// the engine buffer are used (output) or free (input).
+// It also affects the maximum length of the burst.
+#define ADAPTER_EIP97_DMATHRESHOLD_INPUT   0x08
+#define ADAPTER_EIP97_DMATHRESHOLD_OUTPUT  0x08
+
+#ifdef DRIVER_ENABLE_SWAP_MASTER
+// This parameter enables the byte swap in 32-bit words
+// for the EIP-202 CD Manager master interface
+#define ADAPTER_EIP202_CDR_BYTE_SWAP_ENABLE
+
+// This parameter enables the byte swap in 32-bit words
+// for the EIP-202 RD Manager master interface
+#define ADAPTER_EIP202_RDR_BYTE_SWAP_ENABLE
+#endif // DRIVER_ENABLE_SWAP_MASTER
+
+#ifdef DRIVER_SWAPENDIAN
+// This parameter enables the endianness conversion by the Host CPU
+// for the ring descriptors
+#define ADAPTER_EIP202_ARMRING_ENABLE_SWAP
+#endif //DRIVER_SWAPENDIAN
+
+#ifdef DRIVER_INTERRUPTS
+#define ADAPTER_EIP202_INTERRUPTS_ENABLE
+#endif
+
+#ifdef ADAPTER_INTERRUPTS_TRACEFILTER
+#define ADAPTER_EIP202_INTERRUPTS_TRACEFILTER   ADAPTER_INTERRUPTS_TRACEFILTER
+#endif
+
+#ifdef ADAPTER_PEC_BANK_RING
+#define ADAPTER_EIP202_BANK_RING        ADAPTER_PEC_BANK_RING
+#endif
+
+#ifdef ADAPTER_PEC_BANK_SA
+#define ADAPTER_EIP202_BANK_SA          ADAPTER_PEC_BANK_SA
+#endif
+
+// Maximum number of supported EIP-202 devices
+// (one device includes CDR Manager and RDR Manager)
+#ifdef DRIVER_MAX_NOF_RING_TO_USE
+#define ADAPTER_EIP202_DEVICE_COUNT     DRIVER_MAX_NOF_RING_TO_USE
+#else
+#define ADAPTER_EIP202_DEVICE_COUNT     1
+#endif
+
+#define ADAPTER_EIP202_DEVICE_CONF(n) \
+    { \
+        IRQ_CDR##n,       /* CDR IRQ */                \
+        0,                /* CDR IRQ flags */          \
+        "EIP202_CDR" #n,  /* CDR Device Name */        \
+        IRQ_RDR##n,       /* RDR IRQ */                \
+        0,                /* RDR IRQ flags */          \
+        "EIP202_RDR" #n,  /* RDR Device Name */        \
+    }
+
+#define ADAPTER_EIP202_DEVICES \
+ ADAPTER_EIP202_DEVICE_CONF(0), \
+ ADAPTER_EIP202_DEVICE_CONF(1), \
+ ADAPTER_EIP202_DEVICE_CONF(2), \
+ ADAPTER_EIP202_DEVICE_CONF(3), \
+ ADAPTER_EIP202_DEVICE_CONF(4), \
+ ADAPTER_EIP202_DEVICE_CONF(5), \
+ ADAPTER_EIP202_DEVICE_CONF(6), \
+ ADAPTER_EIP202_DEVICE_CONF(7), \
+ ADAPTER_EIP202_DEVICE_CONF(8), \
+ ADAPTER_EIP202_DEVICE_CONF(9), \
+ ADAPTER_EIP202_DEVICE_CONF(10), \
+ ADAPTER_EIP202_DEVICE_CONF(11), \
+ ADAPTER_EIP202_DEVICE_CONF(12), \
+ ADAPTER_EIP202_DEVICE_CONF(13)
+
+
+#if ADAPTER_PEC_DEVICE_COUNT != ADAPTER_EIP202_DEVICE_COUNT
+#error "Adapter PEC device configuration is invalid"
+#endif
+
+#ifdef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+// Define if the hardware uses bits in record pointers to distinguish types.
+#define ADAPTER_EIP202_USE_POINTER_TYPES
+#endif
+
+#ifdef DRIVER_USE_INVALIDATE_COMMANDS
+// Define if record invalidate commands are implemented without extended
+// command and result descriptors.
+#define ADAPTER_EIP202_USE_INVALIDATE_COMMANDS
+// Define if the hardware uses bits in record pointers to distinguish types.
+#define ADAPTER_EIP202_USE_POINTER_TYPES
+#endif
+
+
+// DMA buffer allocation alignment
+#ifdef DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#define ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#endif
+
+// Allow unaligned DMA buffers.
+#ifdef DRIVER_ALLOW_UNALIGNED_DMA
+#define ADAPTER_EIP202_ALLOW_UNALIGNED_DMA
+#endif
+
+// Enable this parameter to switch off the automatic calculation of the global
+// and ring data transfer size and threshold values
+//#define ADAPTER_EIP202_AUTO_THRESH_DISABLE
+
+#ifdef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+#define ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT    16
+#define ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT   12
+#define ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT    80
+#define ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT   20
+#endif
+
+
+/****************************************************************************
+ * Adapter DMAResource handles maximum calculation
+ */
+
+// the number of buffers that can be tracked by the driver-internal
+// administration: ADAPTER_MAX_DMARESOURCE_HANDLES
+#ifndef ADAPTER_REMOVE_BOUNCEBUFFERS
+#define ADAPTER_BOUNCE_FACTOR   2
+#else
+#define ADAPTER_BOUNCE_FACTOR   1
+#endif
+
+// internal DMA-safe buffers are used for rings, they are never bounced
+#ifdef ADAPTER_PEC_SEPARATE_RINGS
+#define ADAPTER_PEC_MAX_RINGS_DMARESOURCE_HANDLES   2
+#else
+#define ADAPTER_PEC_MAX_RINGS_DMARESOURCE_HANDLES   1
+#endif
+
+// SC buffers must be allocated DMA-safe by applications,
+// they are never bounced
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+// 2 separate rings are used, one for gather and one for scatter
+// 1 DMA resource is used for SG list and 1 is extra
+#define ADAPTER_PEC_MAX_SC_DMARESOURCE_HANDLES   \
+    (2+1+ADAPTER_PEC_SC_RING_MAX_DESCRIPTORS+1)
+#else
+#define ADAPTER_PEC_MAX_SC_DMARESOURCE_HANDLES   0
+#endif
+
+
+#define ADAPTER_MAX_DMARESOURCE_HANDLES \
+    (ADAPTER_BOUNCE_FACTOR * \
+     (ADAPTER_PEC_MAX_SAS + \
+     ADAPTER_PEC_DEVICE_COUNT * ADAPTER_PEC_MAX_PACKETS) + \
+     ADAPTER_PEC_MAX_RINGS_DMARESOURCE_HANDLES +         \
+     ADAPTER_PEC_MAX_SC_DMARESOURCE_HANDLES + \
+     ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT)
+
+
+/* end of file cs_adapter.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter_ext.h
new file mode 100644
index 0000000..fccc530
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_adapter_ext.h
@@ -0,0 +1,286 @@
+/* cs_adapter_ext.h
+ *
+ * Configuration Settings for the SLAD Adapter Combined module,
+ * extensions.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_ADAPTER_EXT_H_
+#define CS_ADAPTER_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+* This module uses (requires) the following interface(s):
+ */
+
+// Top-level product configuration
+#include "cs_ddk197.h"
+
+
+/****************************************************************************
+ * Adapter Global configuration parameters
+ */
+
+
+/****************************************************************************
+ * Adapter PEC configuration parameters
+ */
+
+
+/****************************************************************************
+ * Adapter Classification (Global Control) configuration parameters
+ */
+
+// Set to 1 to enable the FLUEC cache, to 0 to disable it.
+#define ADAPTER_CS_FLUE_LOOKUP_CACHED                  0
+
+#ifdef DDK_EIP197_FW_IOTOKEN_METADATA_ENABLE
+// Enable use of meta-data in input and output tokens
+#define ADAPTER_CS_GLOBAL_IOTOKEN_METADATA_ENABLE
+#endif
+
+#ifdef DDK_EIP197_FW_CFH_EBABLE
+// Enable CFH headers.
+#define ADAPTER_CS_GLOBAL_CFH_ENABLE
+#endif
+
+#ifdef DDK_EIP197_SRV_ICEOCE
+#define ADAPTER_CS_GLOBAL_SRV_ICEOCE
+#endif
+#ifdef DDK_EIP197_SRV_ICE
+#define ADAPTER_CS_GLOBAL_SRV_ICE
+#endif
+
+// Enable PktID incrementing on egress tunnel headers.
+//#define ADAPTER_CS_GLOBAL_INCREMENT_PKTID
+
+// ECN control for ingress packets.
+#define ADAPTER_CS_GLOBAL_ECN_CONTROL 0x1f
+
+// Record header alignment for DTLS records headers in decrypted packets.
+#define ADAPTER_CS_GLOBAL_DTLS_HDR_ALIGN 0
+
+// Defer DTLS packets type CCS to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_CCS
+// Defer DTLS packets type Alert to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_ALERT
+// Defer DTLS packets type Handshake to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_HANDSHAKE
+// Defer DTLS packets type AppData to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_APPDATA
+// Defer DTLS packets type CAPWAP to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_CAPWAP
+
+
+/****************************************************************************
+ * Adapter PCL (Flow Control) configuration parameters
+ */
+
+#ifdef DRIVER_DMARESOURCE_BANKS_ENABLE
+
+// Element byte count in the DMA bank
+#ifdef DRIVER_DMA_BANK_ELEMENT_BYTE_COUNT
+#define ADAPTER_TRANSFORM_RECORD_BYTE_COUNT DRIVER_DMA_BANK_ELEMENT_BYTE_COUNT
+#define ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT  DRIVER_DMA_BANK_ELEMENT_BYTE_COUNT
+#endif
+
+// Element count in the DMA bank
+#ifdef DRIVER_DMA_BANK_ELEMENT_COUNT
+#define ADAPTER_TRANSFORM_RECORD_COUNT    DRIVER_DMA_BANK_ELEMENT_COUNT
+#define ADAPTER_PCL_FLOW_RECORD_COUNT     DRIVER_DMA_BANK_ELEMENT_COUNT
+#endif
+
+#endif // DRIVER_DMARESOURCE_BANKS_ENABLE
+
+#ifdef DRIVER_RING_AIC_DISABLE
+#define ADAPTER_EIP202_RING_AIC_DISABLE
+#endif
+
+
+/****************************************************************************
+ * Adapter EIP-202 configuration parameters
+ */
+
+#ifdef ADAPTER_EIP202_RING_AIC_DISABLE
+
+
+// Definition of AIC devices to use in system.
+//                  DeviceName IntNR flag
+// if flag is 0, IntNr refers to one of the interrupts in ADAPTER_EIP202_IRQS
+//   for example IRQ_RING0 and the AIC is connected to an input of another AIC.
+// If flag is 1, IntNr is the index of a system interrupt and the AIC
+//   has a dedicated system interrupt.
+#define ADAPTER_EIP202_AICS \
+    ADAPTER_EIP202_ADD_AIC("EIP201_GLOBAL",  0,  1)
+
+// Definitions of logical interrupts in the system.
+//                 Name PhysBit AICDevName TaskletFlag Polarity.
+// Name is a symbolic constant like IRQ_CDR0, from which an enum will be made.
+// PhysBit is the physical input line of the AIC for this interrupt.
+// AICDevName is the device name of the AIC.
+// TaskletFLag is 1 if the IRQ is to be handled via a tasklet.
+// Polarity is th polarity of the interrupt signal.
+#define ADAPTER_EIP202_IRQS \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_DFE0, 0, "EIP201_GLOBAL", 0, ACTIVE_LOW),  \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_DSE0, 1, "EIP201_GLOBAL", 0, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_PE0, 4, "EIP201_GLOBAL", 0, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR0, 24, "EIP201_GLOBAL", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR0, 25, "EIP201_GLOBAL", 1, ACTIVE_LOW)
+
+#else
+
+#ifdef DRIVER_AIC_SEPARATE_IRQ
+
+// Definition of AIC devices to use in system.
+//                  DeviceName IntNR flag
+// if flag is 0, IntNr refers to one of the interrupts in ADAPTER_EIP202_IRQS
+//   for example IRQ_RING0 and the AIC is connected to an input of another AIC.
+// If flag is 1, IntNr is the index of a system interrupt and the AIC
+//   has a dedicated system interrupt.
+#define ADAPTER_EIP202_AICS \
+    ADAPTER_EIP202_ADD_AIC("EIP201_RING0", 1, 1)
+
+// Definitions of logical interrupts in the system.
+//                 Name PhysBit AICDevName TaskletFlag Polarity.
+// Name is a symbolic constant like IRQ_CDR0, from which an enum will be made.
+// PhysBit is the physical input line of the AIC for this interrupt.
+// AICDevName is the device name of the AIC.
+// TaskletFLag is 1 if the IRQ is to be handled via a tasklet.
+// Polarity is the polarity of the interrupt signal.
+#define ADAPTER_EIP202_IRQS \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR0, 0, "EIP201_RING0", 1, ACTIVE_LOW),   \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR0, 1, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR1, 2, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR1, 3, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR2, 4, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR2, 5, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR3, 6, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR3, 7, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR4, 8, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR4, 9, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR5, 10, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR5, 11, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR6, 12, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR6, 13, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR7, 14, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR7, 15, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR8, 16, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR8, 17, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR9, 18, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR9, 19, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR10, 20, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR10, 21, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR11, 22, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR11, 23, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR12, 24, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR12, 25, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR13, 26, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR13, 27, "EIP201_RING0", 1, ACTIVE_LOW)
+
+
+#else
+
+// Definition of AIC devices to use in system.
+//                  DeviceName IntNR flag
+// if flag is 0, IntNr refers to one of the interrupts in ADAPTER_EIP202_IRQS
+//   for example IRQ_RING0 and the AIC is connected to an input of another AIC.
+// If flag is 1, IntNr is the index of a system interrupt and the AIC
+//   has a dedicated system interrupt.
+#define ADAPTER_EIP202_AICS \
+    ADAPTER_EIP202_ADD_AIC("EIP201_GLOBAL",  0,  1), \
+    ADAPTER_EIP202_ADD_AIC("EIP201_RING0", IRQ_RING0, 0),   \
+    ADAPTER_EIP202_ADD_AIC("EIP201_CS", IRQ_CS, 0)
+
+// Definitions of logical interrupts in the system.
+//                 Name PhysBit AICDevName TaskletFlag Polarity.
+// Name is a symbolic constant like IRQ_CDR0, from which an enum will be made.
+// PhysBit is the physical input line of the AIC for this interrupt.
+// AICDevName is the device name of the AIC.
+// TaskletFLag is 1 if the IRQ is to be handled via a tasklet.
+// Polarity is the polarity of the interrupt signal.
+#define ADAPTER_EIP202_IRQS \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_MST_ERR, 0, "EIP201_GLOBAL", 0, ACTIVE_LOW),  \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CS,  1, "EIP201_GLOBAL", 0, ACTIVE_LOW),  \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_PE0, 4, "EIP201_GLOBAL", 0, ACTIVE_LOW),   \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_DRBG_ERR, 8, "EIP201_CS", 1, ACTIVE_HIGH), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_DRBG_RES, 9, "EIP201_CS", 1, RISING_EDGE), \
+    /* DRBG reseed must be edge sensitive as reseed operation does not */ \
+    /* clear IRQ signal from device immediately */                       \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR0, 0, "EIP201_RING0", 1, ACTIVE_LOW),   \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR0, 1, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR1, 2, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR1, 3, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR2, 4, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR2, 5, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR3, 6, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR3, 7, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR4, 8, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR4, 9, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR5, 10, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR5, 11, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR6, 12, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR6, 13, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR7, 14, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR7, 15, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR8, 16, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR8, 17, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR9, 18, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR9, 19, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR10, 20, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR10, 21, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR11, 22, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR11, 23, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR12, 24, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR12, 25, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_CDR13, 26, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RDR13, 27, "EIP201_RING0", 1, ACTIVE_LOW), \
+    ADAPTER_EIP202_ADD_IRQ(IRQ_RING0, 28, "EIP201_GLOBAL", 0, ACTIVE_LOW)
+
+#endif
+#endif
+
+// Enables the EIP-207 Record Cache interface for DMA banks
+//#define ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+// Enables the EIP-207 Record Cache interface for record cache invalidation
+//#define ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+
+// Enable workaround for spurious TTL underflow error reported in
+// EIP-202 result descriptor
+#define ADAPTER_EIP202_RING_TTL_ERROR_WA
+
+// Driver allows for NULL packet pointers for record invalidation commands
+#define ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+
+// Command Descriptor offset
+#ifdef DDK_EIP202_CD_OFFSET_BYTE_COUNT
+#define ADAPTER_EIP202_CD_OFFSET_BYTE_COUNT     DDK_EIP202_CD_OFFSET_BYTE_COUNT
+#endif
+
+// Result Descriptor offset
+#ifdef DDK_EIP202_RD_OFFSET_BYTE_COUNT
+#define ADAPTER_EIP202_RD_OFFSET_BYTE_COUNT     DDK_EIP202_RD_OFFSET_BYTE_COUNT
+#endif
+
+
+#endif // CS_ADAPTER_EXT_H_
+
+
+/* end of file cs_adapter_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ddk197.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ddk197.h
new file mode 100644
index 0000000..f72ceb9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ddk197.h
@@ -0,0 +1,85 @@
+/* cs_ddk197.h
+ *
+ * Top-level DDK-197 product configuration
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef CS_DDK197_H_
+#define CS_DDK197_H_
+
+// Version string to show at startup
+#define DDK_EIP197_VERSION_STRING "DDK-197-GPL v5.6.1"
+
+// Enable if hardware supports 256-bit sequence number masks natively.
+#define DDK_EIP197_EIP96_SEQMASK_256
+
+// Enable if hardware supports 1024-bit sequence number masks natively.
+//#define DDK_EIP197_EIP96_SEQMASK_1024
+
+// Prevent update information from being appended to the output packet.
+// Update information is used for inbound ESP transport: length, protocol,
+// checksum.
+//#define DDK_EIP197_EIP96_BLOCK_UPDATE_APPEND
+
+// Enable extended error codes from the EIP-96
+#define DDK_EIP197_EXTENDED_ERRORS_ENABLE
+
+// Enable use of meta-data in input and output tokens with the EIP-197 firmware
+// Note: The EIP-197 firmware must support this before in order to be enabled
+#define DDK_EIP197_FW_IOTOKEN_METADATA_ENABLE
+
+// Ring Control: Command Descriptor offset (maximum size), in bytes
+//               16 32-bit words, 64 bytes
+// Note: consider CPU d-cache line size alignment
+//       if the Command Ring buffer is in cached memory!
+#define DDK_EIP202_CD_OFFSET_BYTE_COUNT     128
+
+// Ring Control: Result Descriptor offset (maximum size), in bytes
+//               16 32-bit words, 64 bytes
+// Note: consider CPU d-cache line size alignment
+//       if the Result Ring buffer is in cached memory!
+#define DDK_EIP202_RD_OFFSET_BYTE_COUNT     128
+
+
+/*----------------------------------------------------------------------------
+ * CAUTION: Do not change the parameters below unless
+ *          the EIP-197 hardware configuration changes!
+ */
+
+// EIP-197 Server with ICE configuration and optional OCE
+#define DDK_EIP197_SRV_ICE
+
+// Test Firmware 3.3 features.
+#define DDK_EIP197_FW33_FEATURES
+
+// Firmware supports XFRM API
+#define DDK_EIP197_FW_XFRM_API_
+
+#endif // CS_DDK197_H_
+
+
+/* end of file cs_ddk197.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver.h
new file mode 100644
index 0000000..13401a1
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver.h
@@ -0,0 +1,240 @@
+/* cs_driver.h
+ *
+ * Top-level Product Configuration Settings.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_DRIVER_H
+#define INCLUDE_GUARD_CS_DRIVER_H
+
+#include "cs_systemtestconfig.h"      // defines SYSTEMTEST_CONFIG_Cnn
+
+// Host hardware platform specific extensions
+#include "cs_driver_ext.h"
+
+
+// Driver name used for reporting
+#define DRIVER_NAME     "Security_IP-197"
+
+// activate in case of endianness difference between CPU and EIP
+// to ask driver to swap byte order of all control words
+// we assume that if ARCH is PowerPC, then CPU is big endian
+#ifdef ARCH_POWERPC
+#define DRIVER_SWAPENDIAN
+#endif //ARCH_POWERPC
+
+// Maximum number of Processing Engines (EIP-206) to use
+#define DRIVER_MAX_NOF_PE_TO_USE                       12
+
+// Maximum number of Classification Engines (EIP-207c) to use
+// Note: one Processing Engine includes one Classification Engine
+#define DRIVER_CS_MAX_NOF_CE_TO_USE                    DRIVER_MAX_NOF_PE_TO_USE
+
+// Size (in entries) of the Flow Hash Table (FHT)
+// used by the EIP-207 Classification Engine
+#define DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT             512
+
+// Some applications allocate network packets at unaligned addresses.
+// To avoid bouncing these buffers, you can allow unaligned buffers if
+// caching is properly handled in hardware.
+//#define DRIVER_ALLOW_UNALIGNED_DMA
+
+
+// C0 = ARM, Separate, Interrupt coalescing, BB=Y, Perf=N, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C0
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+#define DRIVER_INTERRUPT_COALESCING
+#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_SAS         64
+#define DRIVER_PEC_MAX_PACKETS     32
+#define DRIVER_MAX_PECLOGICDESCR   32
+#endif
+
+// C1 = ARM, Separate, Polling, BB=N, Perf=N, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C1
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#endif
+
+// C2 = ARM, Separate, Interrupts, BB=N, Perf=N, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C2
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#undef DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT
+#define DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT             64
+#define DRIVER_ALLOW_UNALIGNED_DMA
+#endif
+
+
+// C4 = ARM, Separate, Polling, BB=Yes, Perf=N, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C4
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#endif
+
+// C5 = ARM, Separate, Interrupts, BB=Yes, Perf=N, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C5
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#endif
+
+// C8 = ARM, Polling, Separate, BB=N, Perf=Yes, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C8
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_SAS         64
+#define DRIVER_PEC_MAX_PACKETS     32
+#define DRIVER_MAX_PECLOGICDESCR   32
+#endif
+
+// C9 = ARM, Interrupts, Separate, BB=N, Perf=Yes, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C9
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_SAS         64
+#define DRIVER_PEC_MAX_PACKETS     32
+#define DRIVER_MAX_PECLOGICDESCR   32
+#endif
+
+
+// C11 = ARM, Polling, Separate, BB=Yes, Perf=Yes, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C11
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+#define DRIVER_BOUNCEBUFFERS
+#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_SAS         64
+#define DRIVER_PEC_MAX_PACKETS     32
+#define DRIVER_MAX_PECLOGICDESCR   32
+#endif
+
+// C14 = ARM, Polling, Separate, BB=N, Perf=N, SG=Yes
+#ifdef SYSTEMTEST_CONFIGURATION_C14
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_PACKETS     64
+#define DRIVER_MAX_PECLOGICDESCR   64
+#endif
+
+// C15 = ARM, Interrupts, Separate, BB=N, Perf=N, SG=Yes
+#ifdef SYSTEMTEST_CONFIGURATION_C15
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_PACKETS     64
+#define DRIVER_MAX_PECLOGICDESCR   64
+#endif
+
+// C17 = ARM, Interrupt + Coalescing, Separate, BB=N, Perf=Yes, SG=N
+#ifdef SYSTEMTEST_CONFIGURATION_C17
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+#define DRIVER_INTERRUPTS
+#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+#define DRIVER_PEC_MAX_SAS           64
+#define DRIVER_PEC_MAX_PACKETS       32
+#define DRIVER_MAX_PECLOGICDESCR     32
+#endif
+
+// C18 = ARM, Polling, Separate, BB=N, Perf=No, SG=N Byteswap on
+#ifdef SYSTEMTEST_CONFIGURATION_C18
+//#define DRIVER_PE_TCM
+#define DRIVER_PE_ARM_SEPARATE
+//#define DRIVER_INTERRUPTS
+//#define DRIVER_INTERRUPT_COALESCING
+//#define DRIVER_BOUNCEBUFFERS
+//#define DRIVER_PERFORMANCE
+//#define DRIVER_SCATTERGATHER
+// PLB FPGA does not allow for endianness conversion
+// in the Board Control device slave interface required on x86,
+// so just disable the test
+#ifndef EIP197_BUS_VERSION_PLB
+#define DRIVER_SWAPENDIAN         // Host and device have different endianness
+#ifdef ARCH_POWERPC
+#undef  DRIVER_SWAPENDIAN         // Switch off byte swap by the host processor
+#endif //ARCH_POWERPC
+// Enable byte swap by the Engine slave interface
+#define DRIVER_ENABLE_SWAP_SLAVE
+// Enable byte swap by the Engine master interface
+#define DRIVER_ENABLE_SWAP_MASTER
+#endif // not EIP197_BUS_VERSION_PLB
+#endif // SYSTEMTEST_CONFIGURATION_C18
+
+#ifndef DRIVER_PEC_MAX_SAS
+#define DRIVER_PEC_MAX_SAS                      60
+#endif
+
+
+// EIP-197 hardware specific extensions
+#include "cs_driver_ext2.h"
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_driver.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext.h
new file mode 100644
index 0000000..92189a5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext.h
@@ -0,0 +1,56 @@
+/* cs_driver_ext.h
+ *
+ * Top-level Product Configuration Settings specific for FPGA.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_DRIVER_EXT_H
+#define INCLUDE_GUARD_CS_DRIVER_EXT_H
+
+// Driver license for the module registration with the Linux kernel
+#define DRIVER_LICENSE                                 "GPL"
+
+// FPGA DMA buffer alignment is 8 bytes
+#define DRIVER_DMA_ALIGNMENT_BYTE_COUNT                16
+
+// Enables DMA banks
+#define DRIVER_DMARESOURCE_BANKS_ENABLE
+
+// DMA bank to use for SA bouncing by the PEC API implementation
+#define DRIVER_PEC_BANK_SA                             1 // Static bank
+
+// DMA resource bank for transform records allocation
+// by the PCL API implementation, static bank
+#define DRIVER_PCL_BANK_TRANSFORM                      DRIVER_PEC_BANK_SA
+
+// DMA resource bank for flow records allocation by the PCL API implementation,
+// static bank
+#define DRIVER_PCL_BANK_FLOW                           DRIVER_PCL_BANK_TRANSFORM
+
+// Each static bank for DMA resources must have 2 lists
+#define DRIVER_LIST_HWPAL_MAX_NOF_INSTANCES            2
+
+// Define this it all AIC devices have a separate external IRQ line.
+//#define DRIVER_AIC_SEPARATE_IRQ
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_driver_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext2.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext2.h
new file mode 100644
index 0000000..d43de4c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_driver_ext2.h
@@ -0,0 +1,89 @@
+/* cs_driver_ext2.h
+ *
+ * Top-level Product EIP-197 hardware specific Configuration Settings.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_DRIVER_EXT2_H
+#define INCLUDE_GUARD_CS_DRIVER_EXT2_H
+
+// Disable usage of the EIP-202 Ring Arbiter
+//#define DRIVER_EIP202_RA_DISABLE
+
+// Number of Ring interfaces to use
+#define DRIVER_MAX_NOF_RING_TO_USE                     14
+
+// Maximum number of Flow Look-Up Engines (FLUE in EIP-207s) to use
+#define DRIVER_PCL_MAX_FLUE_DEVICES                 DRIVER_CS_MAX_NOF_CE_TO_USE
+
+// Maximum number of Flow Hash Tables to use in the Classification (PCL) Driver
+#define DRIVER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE      1
+
+// Number of overflow buckets associated with hash table
+#define DRIVER_PCL_FLOW_HASH_OVERFLOW_COUNT  DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT
+
+#ifdef DRIVER_DMARESOURCE_BANKS_ENABLE
+
+// Maximum number of flow records the driver can allocate
+#define DRIVER_FLOW_RECORD_COUNT            \
+                        (DRIVER_PCL_FLOW_HASH_ENTRIES_COUNT + \
+                                    DRIVER_PCL_FLOW_HASH_OVERFLOW_COUNT)
+
+// Flow record size is determined by the EIP-207 Firmware API
+#define DRIVER_FLOW_RECORD_BYTE_COUNT                  64
+
+// Maximum number of SA or transform records the driver can allocate
+#define DRIVER_TRANSFORM_RECORD_COUNT                  DRIVER_PEC_MAX_SAS
+
+// Maximum Transform record size for the static DMA bank
+// For the Look-Aside Basic Crypto flow the transform record size is determined
+// by the maximum used SA size.
+// For all the other flows the transform record size is determined
+// by the EIP-207 Firmware API.
+// The static DMA bank is used only for the Flow and Transform records
+// that can be looked up, e.g. NOT for the Look-Aside Basic Crypto flow.
+#define DRIVER_TRANSFORM_RECORD_BYTE_COUNT             512
+
+// Each static bank for DMA resources must have 2 lists plus
+// each classification engine requires 1 list
+#define DRIVER_LIST_PCL_MAX_NOF_INSTANCES           DRIVER_PCL_MAX_FLUE_DEVICES
+#define DRIVER_LIST_MAX_NOF_INSTANCES              \
+                                (DRIVER_LIST_HWPAL_MAX_NOF_INSTANCES +  \
+                                        DRIVER_LIST_PCL_MAX_NOF_INSTANCES)
+#define DRIVER_LIST_PCL_OFFSET             DRIVER_LIST_HWPAL_MAX_NOF_INSTANCES
+
+// Determine maximum DMA bank element size
+#define DRIVER_DMA_BANK_ELEMENT_BYTE_COUNT      \
+        (DRIVER_FLOW_RECORD_BYTE_COUNT > DRIVER_TRANSFORM_RECORD_BYTE_COUNT ? \
+           DRIVER_FLOW_RECORD_BYTE_COUNT : DRIVER_TRANSFORM_RECORD_BYTE_COUNT)
+
+// Determine maximum number of elements in DMA bank
+#define DRIVER_DMA_BANK_ELEMENT_COUNT           \
+                (DRIVER_FLOW_RECORD_COUNT + DRIVER_TRANSFORM_RECORD_COUNT)
+
+#endif // DRIVER_DMARESOURCE_BANKS_ENABLE
+
+// Driver uses record invalidate commands (with non-extended descriptor format).
+//#define DRIVER_USE_INVALIDATE_COMMANDS
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_driver_ext2.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip201.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip201.h
new file mode 100644
index 0000000..6c72791
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip201.h
@@ -0,0 +1,68 @@
+/* cs_eip201.h
+ *
+ * Configuration Settings for the EIP-201 Driver Library module.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#include "cs_driver.h"      // top-level driver configuration
+
+// set this option to enable checking of all arguments to all EIP201 functions
+// disable it to reduce code size and reduce overhead
+#ifndef DRIVER_PERFORMANCE
+#define EIP201_STRICT_ARGS
+#endif
+
+// maximum number of interrupts as defined for this instance
+#define EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS  29
+
+/* EIP201_REMOVE_*
+ *
+ * These switches allow removal of unused API functions
+ * to reduce footprint and increase code-coverage figures
+ */
+#define EIP201_REMOVE_CONFIG_CHANGE
+#define EIP201_REMOVE_CONFIG_READ
+//#define EIP201_REMOVE_SOURCEMASK_ENABLESOURCE
+//#define EIP201_REMOVE_SOURCEMASK_DISABLESOURCE
+#define EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED
+#define EIP201_REMOVE_SOURCEMASK_READALL
+#define EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING
+#define EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING
+//#define EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+#define EIP201_REMOVE_SOURCESTATUS_READALLRAW
+//#define EIP201_REMOVE_INITIALIZE
+//#define EIP201_REMOVE_ACKNOWLEDGE
+
+#ifdef DRIVER_POLLING
+// disable all functions
+#define EIP201_REMOVE_CONFIG_CHANGE
+#define EIP201_REMOVE_CONFIG_READ
+#define EIP201_REMOVE_SOURCEMASK_ENABLESOURCE
+#define EIP201_REMOVE_SOURCEMASK_DISABLESOURCE
+#define EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED
+#define EIP201_REMOVE_SOURCEMASK_READALL
+#define EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING
+#define EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING
+#define EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+#define EIP201_REMOVE_SOURCESTATUS_READALLRAW
+#define EIP201_REMOVE_INITIALIZE
+#define EIP201_REMOVE_ACKNOWLEDGE
+#endif /* DRIVER_POLLING */
+
+/* end of file cs_eip201.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global.h
new file mode 100644
index 0000000..072b26e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global.h
@@ -0,0 +1,44 @@
+/* cs_eip202_global.h
+ *
+ * Top-level EIP-202 Driver Library Global Control configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP202_GLOBAL_H_
+#define CS_EIP202_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// Configuration parameter extensions#include
+#include "cs_eip202_global_ext.h"
+
+
+#endif /* CS_EIP202_GLOBAL_H_ */
+
+
+/* end of file cs_eip202_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global_ext.h
new file mode 100644
index 0000000..f84d9c2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_global_ext.h
@@ -0,0 +1,64 @@
+/* cs_eip202_global_ext.h
+ *
+ * Top-level EIP-202 Driver Library Global Control configuration extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP202_GLOBAL_EXT_H_
+#define CS_EIP202_GLOBAL_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-202 HIA registers
+ *****************************************************************************/
+
+// HIA DFE all threads
+#define EIP202_DFE_BASE           0x8C000
+
+// HIA DFE thread n (n - number of the DFE thread)
+#define EIP202_DFE_TRD_BASE       0x8C040
+
+// HIA DSE all threads
+#define EIP202_DSE_BASE           0x8D000
+
+// HIA DSE thread n (n - number of the DSE thread)
+#define EIP202_DSE_TRD_BASE       0x8D040
+
+// HIA Ring Arbiter
+#define EIP202_RA_BASE            0x90000
+
+// HIA Global
+#define EIP202_G_BASE             0x9FFF0
+
+
+#endif /* CS_EIP202_GLOBAL_EXT_H_ */
+
+
+/* end of file cs_eip202_global_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring.h
new file mode 100644
index 0000000..ce218dd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring.h
@@ -0,0 +1,138 @@
+/* cs_eip202_ring.h
+ *
+ * Top-level configuration parameters
+ * for the EIP-202 Ring Control Driver Library
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP202_RING_H_
+#define CS_EIP202_RING_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "cs_driver.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Is device 64-bit?
+#ifdef DRIVER_64BIT_DEVICE
+#define EIP202_64BIT_DEVICE
+#endif // DRIVER_64BIT_DEVICE
+
+// Disable clustered write operations, e.g. every write operation to
+// an EIP-202 RD register will be followed by one read operation to
+// a pre-defined EIP-202 register
+#define EIP202_CLUSTERED_WRITES_DISABLE
+
+#ifdef DRIVER_PEC_CD_PROT_VALUE
+#define EIP202_RING_CD_PROT_VALUE               DRIVER_PEC_CD_PROT_VALUE
+#endif
+
+#ifdef DRIVER_PEC_RD_PROT_VALUE
+#define EIP202_RING_RD_PROT_VALUE               DRIVER_PEC_RD_PROT_VALUE
+#endif
+
+#ifdef DRIVER_PEC_DATA_PROT_VALUE
+#define EIP202_RING_DATA_PROT_VALUE             DRIVER_PEC_DATA_PROT_VALUE
+#endif
+
+#ifdef DRIVER_PEC_ACD_PROT_VALUE
+#define EIP202_RING_ACD_PROT_VALUE              DRIVER_PEC_ACD_PROT_VALUE
+#endif
+
+#ifdef EIP197_BUS_VERSION_AXI3
+// For AXI v3
+#define EIP202_RING_CD_RD_CACHE_CTRL            2
+#define EIP202_RING_CD_WR_CACHE_CTRL            2
+#define EIP202_RING_RD_RD_CACHE_CTRL            2
+#define EIP202_RING_RD_WR_CACHE_CTRL            2
+#endif
+
+#ifdef EIP197_BUS_VERSION_AXI4
+// For AXI v4
+#define EIP202_RING_CD_RD_CACHE_CTRL            5
+#define EIP202_RING_CD_WR_CACHE_CTRL            3
+#define EIP202_RING_RD_RD_CACHE_CTRL            5
+#define EIP202_RING_RD_WR_CACHE_CTRL            3
+#endif
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+#ifndef DRIVER_PERFORMANCE
+#define EIP202_RING_STRICT_ARGS
+#endif
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+#ifndef DRIVER_PERFORMANCE
+#define EIP202_RING_DEBUG_FSM
+#endif
+
+// Performance optimization: minimize CD and RD words writes and reads
+#ifdef DRIVER_PERFORMANCE
+#define EIP202_CDR_OPT1
+#endif
+
+#if defined(DRIVER_PE_ARM_SEPARATE)
+#ifndef DRIVER_SCATTERGATHER
+#if defined(DRIVER_64BIT_DEVICE) && !defined(DRIVER_PERFORMANCE)
+// Enables padding the result descriptor to its full programmed offset,
+// 0 - disabled, 1 - enabled
+// Note: when enabled EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG must be defined too
+#define EIP202_RDR_PAD_TO_OFFSET                1
+#endif
+
+// Enable RDR ownership word mechanism
+#define EIP202_RDR_OWNERSHIP_WORD_ENABLE
+
+#endif // !DRIVER_SCATTERGATHER
+#else // DRIVER_PE_ARM_SEPARATE
+#ifndef DRIVER_SCATTERGATHER
+// Application ID field in the result token cannot be used when scatter/gather
+// is enabled because this ID field is only written in the last descriptor
+// in the chain!
+#define EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+#endif // !DRIVER_SCATTERGATHER
+#endif // !DRIVER_PE_ARM_SEPARATE
+
+
+// Bufferability control for result token DMA writes:
+// 0b = do not buffer, 1b = allow buffering
+#define EIP202_RING_RD_RES_BUF                  0
+
+// Bufferability control for descriptor control word DMA writes:
+// 0b = do not buffer, 1b = allow buffering.
+#define EIP202_RING_RD_CTRL_BUF                 0
+
+#include "cs_eip202_ring_ext.h"
+
+#endif /* CS_EIP202_RING_H_ */
+
+
+/* end of file cs_eip202_ring.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring_ext.h
new file mode 100644
index 0000000..1a94e24
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip202_ring_ext.h
@@ -0,0 +1,34 @@
+/* cs_eip202_ring_ext.h
+ *
+ * Top-level configuration parameters extensions
+ * for the EIP-202 Ring Control
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2018-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP202_RING_EXT_H_
+#define CS_EIP202_RING_EXT_H_
+
+// Define to enable a work-around.
+//#define EIP202_RING_BUS_KEEPALIVE_WORKAROUND
+
+#endif /* CS_EIP202_RING_EXT_H_ */
+
+
+/* end of file cs_eip202_ring_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206.h
new file mode 100644
index 0000000..a055d1e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206.h
@@ -0,0 +1,45 @@
+/* cs_eip206.h
+ *
+ * Top-level EIP-206 Driver Library configuration
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP206_H_
+#define CS_EIP206_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// Configuration parameter extensions
+#include "cs_eip206_ext.h"
+
+
+#endif /* CS_EIP206_H_ */
+
+
+/* end of file cs_eip206.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206_ext.h
new file mode 100644
index 0000000..695f4c5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip206_ext.h
@@ -0,0 +1,60 @@
+/* cs_eip206_ext.h
+ *
+ * Top-level EIP-206 Driver Library configuration extensions
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP206_EXT_H_
+#define CS_EIP206_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-206 Processing Engine registers
+ *****************************************************************************/
+
+// Processing Packet Engine n (n - number of the PE)
+// Input Side
+#define EIP206_IN_DBUF_BASE           0xA0000
+#define EIP206_IN_TBUF_BASE           0xA0100
+
+// Output Side
+#define EIP206_OUT_DBUF_BASE          0xA1C00
+#define EIP206_OUT_TBUF_BASE          0xA1D00
+
+// PE Options and Version
+#define EIP206_ARC4_BASE              0xA1FEC
+#define EIP206_VER_BASE               0xA1FF8
+
+
+#endif /* CS_EIP206_EXT_H_ */
+
+
+/* end of file cs_eip206_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow.h
new file mode 100644
index 0000000..b9521be
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow.h
@@ -0,0 +1,86 @@
+/* cs_eip207_flow.h
+ *
+ * Default configuration parameters
+ * for the EIP-207 Flow Control Driver Library
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP207_FLOW_H_
+#define CS_EIP207_FLOW_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_driver.h"
+#include "cs_adapter.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Is device 64-bit?
+#ifdef DRIVER_64BIT_DEVICE
+#define EIP207_64BIT_DEVICE
+#endif  // DRIVER_64BIT_DEVICE
+
+// Maximum number of EIP-207c Classification Engines that can be used
+// Should not exceed the number of engines physically available
+#ifdef ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE
+#define EIP207_FLOW_MAX_NOF_CE_TO_USE  ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE
+#else
+#define EIP207_FLOW_MAX_NOF_CE_TO_USE            1
+#endif
+
+// Maximum supported number of flow hash tables
+#ifdef ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE \
+                           ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#else
+#define EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE     1
+#endif
+
+// enable debug checks
+#ifndef DRIVER_PERFORMANCE
+// Define this parameter for additional consistency checks in the flow
+// control functionality
+#define EIP207_FLOW_CONSISTENCY_CHECK
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+#define EIP207_FLOW_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+#define EIP207_FLOW_DEBUG_FSM
+#endif // DRIVER_PERFORMANCE
+
+
+// Configuration parameter Extensions
+#include "cs_eip207_flow_ext.h"
+
+
+#endif /* CS_EIP207_FLOW_H_ */
+
+
+/* end of file cs_eip207_flow.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow_ext.h
new file mode 100644
index 0000000..1fc78b6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_flow_ext.h
@@ -0,0 +1,82 @@
+/* cs_eip207_flow_ext.h
+ *
+ * Top-level configuration parameters extensions
+ * for the EIP-207 Flow Control Driver Library
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP207_FLOW_EXT_H_
+#define CS_EIP207_FLOW_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// Read/Write register constants
+
+
+/*****************************************************************************
+ * Byte offsets of the EIP-207 HIA registers
+ *****************************************************************************/
+
+
+// Direct Transform Lookup (DTL) hardware is present
+#define EIP207_FLOW_HAVE_DTL
+
+// General Configuration and version, in-flight counters
+#define EIP207_REG_IN_FLIGHT_BASE           0xA1FF0
+
+// Flow Hash Engine (FHASH)
+#define EIP207_FHASH_REG_BASE               0xF68C0
+
+// Flow Look-Up Engine (FLUE) register bank size
+#define EIP207_FLUE_FHT_REG_MAP_SIZE        8192
+
+// EIP-207s Classification Support, FLUE CACHEBASE registers base offset
+#define EIP207_FLUE_FHT1_REG_BASE           0x00000
+
+// EIP-207s Classification Support,
+// Flow Hash Engine (FHASH) registers base offset
+#define EIP207_FLUE_HASH_REG_BASE           0x00100
+
+// EIP-207s Classification Support, FLUE HASHBASE registers base offset
+#define EIP207_FLUE_FHT2_REG_BASE           0x00008
+
+// EIP-207s Classification Support, FLUE SIZE register base offset
+#define EIP207_FLUE_FHT3_REG_BASE           0x00010
+
+// EIP-207s Classification Support, options and version registers base offset
+#define EIP207_FLUE_OPTVER_REG_BASE         0x01FF8
+
+// EIP-207s Classification Support, FLUE Record Cache type - High-Performance
+#define EIP207_FLUE_RC_HP
+
+
+#endif /* CS_EIP207_FLOW_EXT_H_ */
+
+
+/* end of file cs_eip207_flow_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global.h
new file mode 100644
index 0000000..decaea2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global.h
@@ -0,0 +1,94 @@
+/* cs_eip207_global.h
+ *
+ * Top-level configuration parameters
+ * for the EIP-207 Global Control
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP207_GLOBAL_H_
+#define CS_EIP207_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_adapter.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_MAX_NOF_PE_TO_USE DRIVER_MAX_NOF_PE_TO_USE
+
+// Maximum number of EIP-207c Classification Engines that can be used
+#ifdef ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE
+#define EIP207_GLOBAL_MAX_NOF_CE_TO_USE  ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE
+#else
+#define EIP207_GLOBAL_MAX_NOF_CE_TO_USE            1
+#endif
+
+// Maximum supported number of flow hash tables
+#ifdef ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE \
+                           ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#else
+#define EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE     1
+#endif
+
+// Maximum supported number of FRC/TRC/ARC4 cache sets
+#define EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE    1
+
+// Enable firmware version check after the download
+#define EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+
+// ICE Scratchpad RAM size in 128-byte blocks (512 bytes)
+#define EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT         4
+
+// OCE Scratchpad RAM size in 128-byte blocks (512 bytes)
+#define EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT         4
+
+// Disable clustered write operations, e.g. every write operation to
+// an EIP-207 register will be followed by one read operation to
+// a pre-defined EIP-207 register
+#define EIP207_CLUSTERED_WRITES_DISABLE
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+#define EIP207_GLOBAL_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+#define EIP207_GLOBAL_DEBUG_FSM
+
+
+// Configuration parameter extensions
+#include "cs_eip207_global_ext.h"
+
+// Configuration parameter extensions
+#include "cs_eip207_global_ext2.h"
+
+
+#endif /* CS_EIP207_GLOBAL_H_ */
+
+
+/* end of file cs_eip207_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext.h
new file mode 100644
index 0000000..35055a3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext.h
@@ -0,0 +1,158 @@
+/* cs_eip207_global_ext.h
+ *
+ * Top-level configuration parameters extensions
+ * for the EIP-207 Global Control
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP207_GLOBAL_EXT_H_
+#define CS_EIP207_GLOBAL_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLUE_HAVE_VIRTUALIZATION
+
+// Number of interfaces for virtualization.
+#define EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE 15
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-207 registers
+ *****************************************************************************/
+
+
+// EIP-207c Classification Engine n (n - number of the CE)
+// Input Side
+
+// EIP-207c Classification Engine n (n - number of the CE)
+// Input Side
+
+#define EIP207_ICE_REG_SCRATCH_BASE    0xA0800
+#define EIP207_ICE_REG_ADAPT_CTRL_BASE 0xA0C00
+#define EIP207_ICE_REG_PUE_CTRL_BASE   0xA0C80
+#define EIP207_ICE_REG_PUTF_CTRL_BASE  0xA0D00
+#define EIP207_ICE_REG_FPP_CTRL_BASE   0xA0D80
+#define EIP207_ICE_REG_PPTF_CTRL_BASE  0xA0E00
+#define EIP207_ICE_REG_RAM_CTRL_BASE   0xA0FF0
+
+// EIP-207c Classification Engine n (n - number of the CE)
+// Output Side
+
+#define EIP207_OCE_REG_SCRATCH_BASE    0xA1400
+#define EIP207_OCE_REG_ADAPT_CTRL_BASE 0xA1860
+#define EIP207_OCE_REG_PUE_CTRL_BASE   0xA1880
+#define EIP207_OCE_REG_PUTF_CTRL_BASE  0xA1900
+#define EIP207_OCE_REG_FPP_CTRL_BASE   0xA1980
+#define EIP207_OCE_REG_PPTF_CTRL_BASE  0xA1A00
+#define EIP207_OCE_REG_RAM_CTRL_BASE   0xA1BF0
+
+// Output Side: reserved
+
+// Access space for Classification RAM, base offset
+#define EIP207_CS_RAM_XS_SPACE_BASE    0xE0000
+
+// EIP-207s Classification Support module (p - number of the cache set)
+
+// General Record Cache (FRC/TRC/ARC4RC) register interface
+#define EIP207_FRC_REG_BASE            0xF0000
+#define EIP207_TRC_REG_BASE            0xF0800
+#define EIP207_ARC4RC_REG_BASE         0xF1000
+
+// EIP-207s Classification Support, Flow Hash Engine (FHASH)
+#define EIP207_FHASH_REG_BASE          0xF68C0
+
+// EIP-207s Classification Support, Flow Look-Up Engine (FLUE), VM-specific
+#define EIP207_FLUE_CONFIG_REG_BASE     0xF6010
+
+// EIP-207s Classification Support, Flow Look-Up Engine (FLUE)
+#define EIP207_FLUE_REG_BASE            0xF6808
+
+#ifdef EIP207_FLUE_HAVE_VIRTUALIZATION
+#define EIP207_FLUE_IFC_LUT_REG_BASE    0xF6820
+#endif
+
+#define EIP207_FLUE_ENABLED_REG_BASE    0xF6840
+
+// EIP-207s Classification Support, Flow Look-Up Engine Cache (FLUEC) Control
+#define EIP207_FLUEC_REG_BASE           0xF6880
+
+// Flow Look-Up Engine Cache (FLUEC) Control
+#define EIP207_FLUEC_REG_INV_BASE       0xF688C
+
+// EIP-207s Classification Support, DMA Control
+#define EIP207_CS_DMA_REG_BASE          0xF7000
+
+// EIP-207s Classification Support, Options and Versions
+#define EIP207_CS_REG_BASE              0xF7FF0
+
+// Size of the Flow Record Cache (administration RAM) in 32-bit words
+#define EIP207_FRC_ADMIN_RAM_WORD_COUNT             320
+
+// Size of the Flow Record Cache (data RAM) in 32-bit words
+#define EIP207_FRC_RAM_WORD_COUNT                   768
+
+
+// Size of the Transform Record Cache (administration RAM) in 32-bit words
+// 80 * 4 = 320 32-bit words for EIP-197 configurations b and c
+// 320 * 4 = 1280 32-bit words for EIP-197 configurations d and e
+//
+// Size of the Transform Record Cache (data RAM) in 32-bit words
+// 480 * 8 = 3840 32-bit words for EIP-197 configurations b and c
+// 1920 * 4 = 15360 32-bit words for EIP-197 configurations d and e
+#if EIP207_MAX_NOF_PE_TO_USE > 1
+#define EIP207_TRC_ADMIN_RAM_WORD_COUNT             16384
+#define EIP207_TRC_RAM_WORD_COUNT                   131072
+#else
+#define EIP207_TRC_ADMIN_RAM_WORD_COUNT             3840
+#define EIP207_TRC_RAM_WORD_COUNT                   15360
+#endif
+
+// Size of the ARC4 Record Cache (administration RAM) in 32-bit words
+#define EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT          0
+
+// Size of the ARC4 Record Cache (data RAM) in 32-bit words
+#define EIP207_ARC4RC_RAM_WORD_COUNT                0
+
+// Input Pull-Up Engine Program RAM size (in 32-bit words), 16KB
+#define EIP207_IPUE_PROG_RAM_WORD_COUNT             4096
+
+// Input Flow Post-Processor Engine Program RAM size (in 32-bit words), 16KB
+#define EIP207_IFPP_PROG_RAM_WORD_COUNT             4096
+
+// Output Pull-Up Engine Program RAM size (in 32-bit words), 16KB
+#define EIP207_OPUE_PROG_RAM_WORD_COUNT             4096
+
+// Output Flow Post-Processor Engine Program RAM size (in 32-bit words), 16KB
+#define EIP207_OFPP_PROG_RAM_WORD_COUNT             4096
+
+
+#endif /* CS_EIP207_GLOBAL_EXT_H_ */
+
+
+/* end of file cs_eip207_global_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext2.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext2.h
new file mode 100644
index 0000000..afda3c7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip207_global_ext2.h
@@ -0,0 +1,36 @@
+/* cs_eip207_global_ext2.h
+ *
+ * Top-level configuration parameters extensions
+ * for the EIP-207 Global Control
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2018-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP207_GLOBAL_EXT2_H_
+#define CS_EIP207_GLOBAL_EXT2_H_
+
+// Define to disable the FRC
+//#define EIP207_GLOBAL_FRC_DISABLE
+
+
+
+#endif /* CS_EIP207_GLOBAL_EXT2_H_ */
+
+
+/* end of file cs_eip207_global_ext2.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip74.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip74.h
new file mode 100644
index 0000000..70a2f93
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip74.h
@@ -0,0 +1,45 @@
+/* cs_eip74.h
+ *
+ * Top-level EIP-74 Driver Library configuration
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP74_H_
+#define CS_EIP74_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "cs_driver.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#ifndef DRIVER_PERFORMANCE
+#define EIP74_STRICT_ARGS
+#endif
+
+#endif /* CS_EIP74_H_ */
+
+
+/* end of file cs_eip74.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96.h
new file mode 100644
index 0000000..0918120
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96.h
@@ -0,0 +1,45 @@
+/* cs_eip96.h
+ *
+ * Top-level EIP-96 Driver Library configuration
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP96_H_
+#define CS_EIP96_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// Configuration parameter extensions
+#include "cs_eip96_ext.h"
+
+
+#endif /* CS_EIP96_H_ */
+
+
+/* end of file cs_eip96.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96_ext.h
new file mode 100644
index 0000000..d7b27a6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip96_ext.h
@@ -0,0 +1,56 @@
+/* cs_eip96_ext.h
+ *
+ * Top-level EIP-96 Driver Library configuration extensions
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP96_EXT_H_
+#define CS_EIP96_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-96 Packet Engine registers
+ *****************************************************************************/
+
+// Processing Packet Engine n (n - number of the DSE thread)
+#define EIP96_CONF_BASE                    0xA1000
+
+// EIP-96 PRNG
+#define EIP96_PRNG_BASE                    0xA1040
+
+// EIP-96 Options and Version
+#define EIP96_VER_BASE                     0xA13F8
+
+
+#endif /* CS_EIP96_EXT_H_ */
+
+
+/* end of file cs_eip96_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global.h
new file mode 100644
index 0000000..993763b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global.h
@@ -0,0 +1,224 @@
+/* cs_eip97_global.h
+ *
+ * Top-level configuration parameters
+ * for the EIP-97 Global Control Driver Library
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP97_GLOBAL_H_
+#define CS_EIP97_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "cs_driver.h"
+
+// Top-level product configuration
+#include "cs_ddk197.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Number of Processing Engines to use
+// Maximum number of processing that should be used
+// Should not exceed the number of engines physically available
+#ifdef DRIVER_MAX_NOF_PE_TO_USE
+#define EIP97_GLOBAL_MAX_NOF_PE_TO_USE       DRIVER_MAX_NOF_PE_TO_USE
+#endif
+
+// Number of Ring interfaces
+// Maximum number of Ring interfaces that should be used
+// Should not exceed the number of rings physically available
+#ifdef DRIVER_MAX_NOF_RING_TO_USE
+#define EIP97_GLOBAL_MAX_NOF_RING_TO_USE     DRIVER_MAX_NOF_RING_TO_USE
+#endif
+
+#ifdef DRIVER_ENABLE_SWAP_SLAVE
+#define EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+#endif
+
+#ifdef DRIVER_GLOBAL_SUPPORT_PROTECT_VALUE
+#define EIP97_GLOBAL_SUPPORT_PROTECT_VALUE   DRIVER_GLOBAL_SUPPORT_PROTECT_VALUE
+#endif
+
+#if defined(EIP197_BUS_VERSION_AXI3)
+// For AXI v3
+#define EIP97_GLOBAL_BUS_BURST_SIZE          3
+#define EIP97_GLOBAL_RD_CACHE_VALUE          2
+#define EIP97_GLOBAL_WR_CACHE_VALUE          2
+#define EIP97_GLOBAL_DFE_DATA_CACHE_CTRL     2
+#define EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL     2
+#define EIP97_GLOBAL_DSE_DATA_CACHE_CTRL     2
+#define EIP97_GLOBAL_TIMEOUT_VALUE           0x3F
+#elif defined(EIP197_BUS_VERSION_AXI4)
+// For AXI v4
+#define EIP97_GLOBAL_BUS_BURST_SIZE          4
+#define EIP97_GLOBAL_RD_CACHE_VALUE          0xA
+#define EIP97_GLOBAL_WR_CACHE_VALUE          6
+#define EIP97_GLOBAL_DFE_DATA_CACHE_CTRL     5
+#define EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL     0
+#define EIP97_GLOBAL_DSE_DATA_CACHE_CTRL     3
+#define EIP97_GLOBAL_TIMEOUT_VALUE           0x3F
+#elif defined(EIP197_BUS_VERSION_PLB)
+// For PLB
+#define EIP97_GLOBAL_BUS_BURST_SIZE          7
+#define EIP97_GLOBAL_TIMEOUT_VALUE           0
+#else
+#error "Error: EIP97_BUS_VERSION_[PLB|AXI3|AXI4] not configured"
+#endif
+
+#ifdef DRIVER_ENABLE_SWAP_MASTER
+// Enable Flow Lookup Data Endianness Conversion
+// by the Classification Engine hardware master interface
+#define EIP97_GLOBAL_BYTE_SWAP_FLUE_DATA
+
+// Enable Flow Record Data Endianness Conversion
+// by the Classification Engine hardware master interface
+#define EIP97_GLOBAL_BYTE_SWAP_FLOW_DATA
+
+// Enable Context Data Endianness Conversion
+// by the Processing Engine hardware master interface
+#define EIP97_GLOBAL_BYTE_SWAP_CONTEXT_DATA
+
+// Enable ARC4 Context Data Endianness Conversion
+// by the PE hardware master interface
+#define EIP97_GLOBAL_BYTE_SWAP_ARC4_CONTEXT_DATA
+
+// One or several of the following methods must be configured:
+// Swap bytes within each 32 bit word
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD_32
+// Swap 32 bit chunks within each 64 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_64
+// Swap 64 bit chunks within each 128 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_128
+// Swap 128 bit chunks within each 256 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_256
+#endif
+
+/* Assume no byte swap required for inline interface, regardless of machine
+   architecture */
+#define EIP202_INLINE_IN_PKT_BYTE_SWAP_METHOD 0
+#define EIP202_INLINE_OUT_PKT_BYTE_SWAP_METHOD 0
+
+// Packet Engine hold output data.
+// This parameter can be used for the in-place packet transformations when
+// the transformed result packet is larger than the original packet.
+// In-place means that the same packet buffer is used to store the original
+// as well as the transformed packet data.
+// This value of this parameter defines the number of last the 8-byte blocks
+// that the packet engine will hold in its internal result packet buffer
+// until the packet processing is completed.
+#ifdef DRIVER_PE_HOLD_OUTPUT_DATA
+#define EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA      \
+                                DRIVER_PE_HOLD_OUTPUT_DATA
+#endif // EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA
+
+
+#ifdef DDK_EIP197_EIP96_BLOCK_UPDATE_APPEND
+// if nonzero, packet update information (checksum, length, protocol) will
+// not be appended to packet data. Indicate in result token flags
+// which fields have to be updated.
+// If zero, such update information can be appended to the packet, if the
+// packet cannot be updated in-place by the hardware.
+#define EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND          1
+
+// If nonzero, add an IP length delta field to the result token.
+#define EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE             1
+#else
+// if nonzero, packet update information (checksum, length, protocol) will
+// not be appended to packet data. Indicate in result token flags
+// which fields have to be updated.
+// If zero, such update information can be appended to the packet, if the
+// packet cannot be updated in-place by the hardware.
+#define EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND          0
+
+// If nonzero, add an IP length delta field to the result token.
+#define EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE             0
+#endif
+
+
+// Enable advance threshold mode for optimal performance and
+// latency compensation in the internal engine buffers
+#define EIP97_GLOBAL_DFE_ADV_THRESH_MODE_FLAG           1
+
+// Maximum EIP-96 token size in 32-bit words: 2^EIP97_GLOBAL_MAX_TOKEN_SIZE
+// Note: The EIP-96 Token Builder may not use larger tokens!
+#define EIP97_GLOBAL_MAX_TOKEN_SIZE                     7
+
+// Define this parameter for automatic calculation of the EIP-202 and EIP-206
+// Global Control threshold values.
+// If not defined then the statically configured values will be used.
+#define EIP97_GLOBAL_THRESH_CONFIG_AUTO
+
+#ifndef EIP97_GLOBAL_THRESH_CONFIG_AUTO
+// Example static EIP-202 and EIP-206 Global Control threshold configuration
+// for optimal performance
+#define EIP97_GLOBAL_DFE_MIN_DATA_XFER_SIZE     5
+#define EIP97_GLOBAL_DFE_MAX_DATA_XFER_SIZE     9
+
+#define EIP97_GLOBAL_DSE_MIN_DATA_XFER_SIZE     7
+#define EIP97_GLOBAL_DSE_MAX_DATA_XFER_SIZE     8
+
+#define EIP97_GLOBAL_DFE_MIN_TOKEN_XFER_SIZE    5
+#define EIP97_GLOBAL_DFE_MAX_TOKEN_XFER_SIZE    EIP97_GLOBAL_MAX_TOKEN_SIZE
+#endif
+
+#ifdef DRIVER_EIP202_RA_DISABLE
+// Disable usage of the EIP-202 Ring Arbiter
+#define EIP202_RA_DISABLE
+#endif
+
+// EIP-96 Packet Engine Enable extended errors
+// When set to 1 E14 indicates the presence of extended errors. If an extended
+//               error is present the error code is in E7..E0.
+// When set to 0 errors will always be reported one-hot in E14..E0
+#ifdef DDK_EIP197_EXTENDED_ERRORS_ENABLE
+#define EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE   1
+#else
+#define EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE   0
+#endif
+
+// Outbound sequence number threshold for reporting imminent rollover (32-bit)
+#define EIP97_GLOBAL_EIP96_NUM32_THR            0xffffff80
+
+// Outbound sequence number threshold for reporting imminent rollover (64-bit)
+#define EIP97_GLOBAL_EIP96_NUM64_THR_L          0xffffff00
+#define EIP97_GLOBAL_EIP96_NUM64_THR_H          0xffffffff
+
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+#define EIP97_GLOBAL_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+#define EIP97_GLOBAL_DEBUG_FSM
+
+// Configuration parameter extensions
+#include "cs_eip97_global_ext.h"
+
+
+#endif /* CS_EIP97_GLOBAL_H_ */
+
+
+/* end of file cs_eip97_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global_ext.h
new file mode 100644
index 0000000..3259502
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_eip97_global_ext.h
@@ -0,0 +1,110 @@
+/* cs_eip97_global_ext.h
+ *
+ * Top-level configuration parameters extensions
+ * for the EIP-97 Global Control Driver Library
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_EIP97_GLOBAL_EXT_H_
+#define CS_EIP97_GLOBAL_EXT_H_
+
+#include "cs_ddk197.h"
+#include "cs_adapter.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Define this parameter in order to configure the DFE and DSE ring priorities
+//#define EIP97_GLOBAL_DFE_DSE_PRIO_CONFIGURE
+
+// EIP-207s Classification Support, DMA Control base address
+//#define EIP97_RC_BASE      0x37000
+#define EIP97_RC_BASE      0xF7000
+
+// EIP-207s Classification Support, DMA Control base address
+//#define EIP97_BASE         0x3FFF4
+#define EIP97_BASE         0xFFFF4
+
+//Define if the hardware ECN registers are included
+#define EIP97_GLOBAL_HAVE_ECN_FIXUP
+
+#ifdef EIP97_GLOBAL_HAVE_ECN_FIXUP
+#ifdef ADAPTER_CS_GLOBAL_ECN_CONTROL
+#define EIP97_GLOBAL_EIP96_ECN_CONTROL ADAPTER_CS_GLOBAL_ECN_CONTROL
+#endif
+#endif
+
+// Numbers of the look-aside FIFO queues
+// EIP-197 configuration:
+//           b - 1, c - 3, d - 5, e - 1
+// Leave this undefined for devices without LA FIFO queues (Mobile).
+#define EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE          1
+
+
+// Numbers of the Inline FIFO queues
+// Leave this undefined for devices without Inline FIFO queues (Mobile).
+#define EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE          1
+
+// Enables DSE single write mode, Set to 1 for optimal performance.
+// Applicable only for configurations with
+// - Non-overlapping rings and
+// - 64-bit DMA address descriptor format
+#if defined(DRIVER_PE_ARM_SEPARATE) && defined(DRIVER_64BIT_DEVICE)
+#define EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG      1
+#endif
+
+// Data write bufferability control,
+// for the Look-Aside FIFO streaming interface only
+// Note: when the LA FIFO is not used then set this to 3 for optimal performance
+#define EIP97_GLOBAL_DSE_BUFFER_CTRL                3
+
+// Determines the maximum burst size that will be used on the receive side
+// of the AXI interface or
+// secondary requesting and priority for the PLB interface
+#if defined(EIP197_BUS_VERSION_AXI3)
+// For AXI v3
+#define EIP97_GLOBAL_RX_BUS_BURST_SIZE       3
+#elif defined(EIP197_BUS_VERSION_AXI4)
+// For AXI v4
+#define EIP97_GLOBAL_RX_BUS_BURST_SIZE       4
+#elif defined(EIP197_BUS_VERSION_PLB)
+// For PLB
+#define EIP97_GLOBAL_RX_BUS_BURST_SIZE       5
+#else
+#error "Error: EIP97_BUS_VERSION_[PLB|AXI3|AXI4] not configured"
+#endif
+
+
+// Burst size of inline interface
+#define EIP202_INLINE_BURST_SIZE  2
+
+// Force in-order on inline interface.
+#define EIP202_INLINE_FORCE_INORDER 1
+
+// EIP96 context size in words
+#ifdef DDK_EIP197_EIP96_SEQMASK_1024
+#define EIP97_EIP96_CTX_SIZE 0x52
+#endif
+
+#endif /* CS_EIP97_GLOBAL_EXT_H_ */
+
+
+/* end of file cs_eip97_global_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal.h
new file mode 100644
index 0000000..7395981
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal.h
@@ -0,0 +1,139 @@
+/* cs_hwpal.h
+ *
+ * Configuration Settings for Driver Framework Implementation
+ * for the Security-IP-197 Driver.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_HWPAL_H
+#define INCLUDE_GUARD_CS_HWPAL_H
+
+// we accept a few settings from the top-level configuration file
+#include "cs_driver.h"
+#include "cs_adapter.h"
+
+// Host hardware platform specific extensions
+#include "cs_hwpal_ext.h"
+
+// Total number of devices allowed, must be at least as last as static list.
+#define HWPAL_DEVICE_COUNT 40
+
+// logging level for HWPAL Device
+// Choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#undef LOG_SEVERITY_MAX
+#ifdef DRIVER_PERFORMANCE
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_CRITICAL
+#else // DRIVER_PERFORMANCE
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_WARN
+#endif // DRIVER_PERFORMANCE
+
+// maximum allowed length for a device name
+#define HWPAL_MAX_DEVICE_NAME_LENGTH 64
+
+#define HWPAL_DEVICE_MAGIC   54333
+
+#ifdef DRIVER_NAME
+#define HWPAL_DRIVER_NAME DRIVER_NAME
+#endif
+
+#ifdef DRIVER_ALLOW_UNALIGNED_DMA
+#define HWPAL_DRMARESOURCE_ALLOW_UNALIGNED_ADDRESS
+#endif
+
+// Trace memory leaks for DMAResource API implementation
+#define HWPAL_TRACE_DMARESOURCE_LEAKS
+
+// Is host platform 64-bit?
+#ifdef DRIVER_64BIT_HOST
+#define HWPAL_64BIT_HOST
+// Is device 64-bit? Only makes sense on 64-bit host.
+#ifdef DRIVER_64BIT_DEVICE
+#define HWPAL_DMARESOURCE_64BIT
+#endif  // DRIVER_64BIT_DEVICE
+#endif  // DRIVER_64BIT_HOST
+
+// only define this if the platform hardware guarantees cache coherence of
+// DMA buffers, i.e. when SW does not need to do coherence management.
+#ifdef ARCH_X86
+#define HWPAL_ARCH_COHERENT
+#else
+#undef HWPAL_ARCH_COHERENT
+#if defined(ARCH_ARM) || defined(ARCH_ARM64)
+//#define HWPAL_DMARESOURCE_ARM_DCACHE_CTRL
+//#define HWPAL_DMARESOURCE_CACHE_LINE_BYTE_COUNT 32
+#endif // defined(ARCH_ARM) || defined(ARCH_ARM64)
+#endif
+
+// Logging / tracing control
+#ifndef DRIVER_PERFORMANCE
+#define HWPAL_STRICT_ARGS_CHECK
+#define HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+#ifdef ARCH_X86
+// Enabled for DMAResource API implementation on x86 debugging purposes only
+#undef HWPAL_ARCH_COHERENT
+#endif
+//#define HWPAL_TRACE_DEVICE_FIND
+//#define HWPAL_TRACE_DEVICE_READ
+//#define HWPAL_TRACE_DEVICE_WRITE
+//#define HWPAL_TRACE_DMARESOURCE_WRITE
+//#define HWPAL_TRACE_DMARESOURCE_READ
+//#define HWPAL_TRACE_DMARESOURCE_PREPOSTDMA
+//#define HWPAL_TRACE_DMARESOURCE_BUF
+#endif
+
+// Use sleepable or non-sleepable lock ?
+//#define HWPAL_LOCK_SLEEPABLE
+
+#define HWPAL_DMA_NRESOURCES     ADAPTER_MAX_DMARESOURCE_HANDLES
+
+// Use direct I/O bypassing the OS functions,
+// I/O device must swap bytes in words
+#ifdef DRIVER_ENABLE_SWAP_SLAVE
+#define HWPAL_DEVICE_DIRECT_MEMIO
+#endif
+
+// Enable use of UMDevXS device
+// Note: This parameter must be used for the Driver GC, PEC or PEC-PCL build!
+#ifdef DRIVER_USE_SHDEVXS_DEVICE
+#define HWPAL_USE_UMDEVXS_DEVICE
+#endif
+
+// DMA buffer allocation alignment
+#ifdef DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#define HWPAL_DMARESOURCE_DMA_ALIGNMENT_BYTE_COUNT      \
+                                        DRIVER_DMA_ALIGNMENT_BYTE_COUNT
+#endif
+
+// Performance optimization: disable _Write32/Read32() resource handle validation
+#ifdef DRIVER_PERFORMANCE
+#define HWPAL_DMARESOURCE_OPT1
+#endif
+
+// Performance optimization: disable _Write32/Read32() endianness conversion branch
+#ifdef DRIVER_PERFORMANCE
+#ifndef DRIVER_SWAPENDIAN
+#define HWPAL_DMARESOURCE_OPT2
+#endif
+#endif
+
+
+#endif // INCLUDE_GUARD_CS_HWPAL_H
+
+
+/* end of file cs_hwpal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_ext.h
new file mode 100644
index 0000000..61576e4
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_ext.h
@@ -0,0 +1,120 @@
+/* cs_hwpal_ext.h
+ *
+ * Security-IP-197 (FPGA) PCI chip specific configuration parameters
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_HWPAL_EXT_H_
+#define CS_HWPAL_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// For obtaining the IRQ number
+#ifdef DRIVER_INTERRUPTS
+#define HWPAL_INTERRUPTS
+#endif
+
+// Disable PCI Configuration Space support support
+#define HWPAL_REMOVE_DEVICE_PCICONFIGSPACE
+
+// Device name in the Device Tree Structure
+#define HWPAL_PLATFORM_DEVICE_NAME  "security-ip-197-srv"
+
+// Max number of IRQ's supported by device
+#define HWPAL_PLATFORM_IRQ_COUNT    1
+
+// Index of the IRQ in the "interrupts" property of the Open Firmware device
+// tree entry. 0 is the first IRQ listed, 1 is the second IRQ listed, etc.
+#define HWPAL_PLATFORM_IRQ_IDX      0
+
+#define HWPAL_REMAP_ADDRESSES       ;
+
+// definition of static resources inside the PCI device
+// Refer to the data sheet of device for the correct values
+//                       Name         DevNr  Start    Last  Flags (see below)
+#define HWPAL_DEVICES \
+        HWPAL_DEVICE_ADD("EIP197_GLOBAL", 0, 0,       0xfffff, 7),  \
+        HWPAL_DEVICE_ADD("EIP207_FLUE0",  0, 0x00000, 0x01fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR0",   0, 0x80000, 0x80fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR0",   0, 0x80000, 0x80fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR1",   0, 0x81000, 0x81fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR1",   0, 0x81000, 0x81fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR2",   0, 0x82000, 0x82fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR2",   0, 0x82000, 0x82fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR3",   0, 0x83000, 0x83fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR3",   0, 0x83000, 0x83fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR4",   0, 0x84000, 0x84fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR4",   0, 0x84000, 0x84fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR5",   0, 0x85000, 0x85fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR5",   0, 0x85000, 0x85fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR6",   0, 0x86000, 0x86fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR6",   0, 0x86000, 0x86fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR7",   0, 0x87000, 0x87fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR7",   0, 0x87000, 0x87fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR8",   0, 0x88000, 0x88fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR8",   0, 0x88000, 0x88fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR9",   0, 0x89000, 0x89fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR9",   0, 0x89000, 0x89fff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR10",   0, 0x8a000, 0x8afff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR10",   0, 0x8a000, 0x8afff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR11",   0, 0x8b000, 0x8bfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR11",   0, 0x8b000, 0x8bfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR12",   0, 0x8c000, 0x8cfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR12",   0, 0x8c000, 0x8cfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_CDR13",   0, 0x8d000, 0x8dfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP202_RDR13",   0, 0x8d000, 0x8dfff, 7),  \
+        HWPAL_DEVICE_ADD("EIP201_GLOBAL", 0, 0x9f800, 0x9f8ff, 7),  \
+        HWPAL_DEVICE_ADD("EIP201_RING0",  0, 0x9e800, 0x9e8ff,  7),  \
+        HWPAL_DEVICE_ADD("EIP201_RING1",  0, 0x9d800, 0x9d8ff,  7),  \
+        HWPAL_DEVICE_ADD("EIP201_RING2",  0, 0x9c800, 0x9c8ff,  7),  \
+        HWPAL_DEVICE_ADD("EIP201_RING3",  0, 0x9b800, 0x9b8ff,  7),  \
+        HWPAL_DEVICE_ADD("EIP74",         0, 0xf7000, 0xf707f,  7),  \
+        HWPAL_DEVICE_ADD("EIP201_CS",     0, 0xf7800, 0xf78ff,  7)
+
+// Flags:
+//   bit0 = Trace reads (requires HWPAL_TRACE_DEVICE_READ)
+//   bit1 = Trace writes (requires HWPAL_TRACE_DEVICE_WRITE)
+//   bit2 = Swap word endianness (requires HWPAL_DEVICE_ENABLE_SWAP)
+
+// Note: HWPAL_DEVICES must be aligned with UMDEVXS_DEVICES in cs_umdevxs.h
+
+// Enables DMA resources banks so that different memory regions can be used
+// for DMA buffer allocation
+#ifdef DRIVER_DMARESOURCE_BANKS_ENABLE
+#define HWPAL_DMARESOURCE_BANKS_ENABLE
+#endif // DRIVER_DMARESOURCE_BANKS_ENABLE
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+// Definition of DMA banks, one dynamic and 1 static
+//                                 Bank    Type   Shared  Cached  Addr  Blocks   Block Size
+#define HWPAL_DMARESOURCE_BANKS                                                              \
+        HWPAL_DMARESOURCE_BANK_ADD (0,       0,     0,      1,      0,    0,         0),     \
+        HWPAL_DMARESOURCE_BANK_ADD (1,       1,     1,      1,      0,                       \
+                                    DRIVER_DMA_BANK_ELEMENT_COUNT,                           \
+                                    DRIVER_DMA_BANK_ELEMENT_BYTE_COUNT)
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+
+#endif /* CS_HWPAL_EXT_H_ */
+
+
+/* end of file cs_hwpal_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_lkm.h
new file mode 100644
index 0000000..078e833
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_lkm.h
@@ -0,0 +1,64 @@
+/* cs_hwpal_lkm.h
+ *
+ * Configuration Settings for Driver Framework Implementation for
+ * Linux kernel-space.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_HWPAL_LKM_H
+#define INCLUDE_GUARD_CS_HWPAL_LKM_H
+
+// we accept a few settings from the top-level configuration file
+#include "cs_hwpal.h"
+
+//Define this to override the overall HWPAL log level.
+//#define HWPAL_LKM_LOG_SEVERITY  LOG_SEVERITY_WARN
+#ifdef HWPAL_LKM_LOG_SEVERITY
+#undef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX HWPAL_LKM_LOG_SEVERITY
+#endif
+
+#ifdef ARCH_ARM64
+// Enable cache-coherent DMA buffer allocation
+#define HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+#endif
+
+#if defined(ARCH_ARM) || defined(ARCH_ARM64)
+// Use non-cached DMA buffer mapping
+#define HWPAL_DMARESOURCE_UNCACHED_MAPPING
+
+// Use non-cached DMA buffer allocation
+//#define HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+// Use minimum required cache-control functionality for DMA-safe buffers
+//#define HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+//#define HWPAL_DMARESOURCE_DIRECT_DCHACHE_CONTROL
+//#define HWPAL_DMARESOURCE_DSB_ENABLE
+#endif // defined(ARCH_ARM) || defined(ARCH_ARM64)
+
+#if defined(DRIVER_SWAPENDIAN) && defined(DRIVER_ENABLE_SWAP_SLAVE)
+#define HWPAL_DEVICE_ENABLE_SWAP
+#endif // DRIVER_SWAPENDIAN
+
+
+#endif // INCLUDE_GUARD_CS_HWPAL_LKM_H
+
+
+/* end of file cs_hwpal_lkm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_umdevxs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_umdevxs.h
new file mode 100644
index 0000000..716897f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_hwpal_umdevxs.h
@@ -0,0 +1,91 @@
+/* cs_hwpal_umdevxs.h
+ *
+ * Configuration for Driver Framework Device API implementation for
+ * Linux user-space.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_HWPAL_UMDEVXS_H
+#define INCLUDE_GUARD_CS_HWPAL_UMDEVXS_H
+
+// we accept a few settings from the top-level configuration file
+#include "cs_hwpal.h"
+
+//Define this to override the overall HWPAL log level.
+//#define HWPAL_UMDEVXS_LOG_SEVERITY  LOG_SEVERITY_WARN
+#ifdef HWPAL_UMDEVXS_LOG_SEVERITY
+#undef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX HWPAL_UMDEVXS_LOG_SEVERITY
+#endif
+
+#define HWPAL_DEVICE0_UMDEVXS  HWPAL_DEVICE_TO_FIND
+
+// Check if the endianness conversion must be performed
+#ifdef DRIVER_SWAPENDIAN
+#define HWPAL_DEVICE_ENABLE_SWAP
+#endif // DRIVER_SWAPENDIAN
+
+// Remove Attach/Detach functions.
+#define HWPAL_DMARESOURCE_REMOVE_ATTACH
+
+// Enable cache-coherent DMA buffer allocation
+#ifdef ARCH_X86
+#define HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+//#define HWPAL_DMARESOURCE_UMDEVXS_DCACHE_CTRL
+#endif // ARCH_X86
+
+#if defined(ARCH_ARM) || defined(ARCH_ARM64)
+// Use non-cached DMA buffer allocation and mapping to user-space
+#define HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+
+//#define HWPAL_DMARESOURCE_UMDEVXS_DCACHE_CTRL
+
+// Use minimum required cache-control functionality for DMA-safe buffers
+//#define HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+
+// Use low-level instructions to clean and invalidate d-cache
+//#define HWPAL_DMARESOURCE_DIRECT_DCACHE_CONTROL
+
+// Enables Data cache control (flush / invalidate cache lines) for the ARM CPU
+//#define HWPAL_DMARESOURCE_ARM_DCACHE_CTRL
+
+// D-cache Store Buffer is used
+//#define HWPAL_DMARESOURCE_DSB_ENABLE
+#endif // defined(ARCH_ARM) || defined(ARCH_ARM64)
+
+#ifdef ARCH_POWERPC
+// Use low-level instructions to clean and invalidate d-cache
+#define HWPAL_DMARESOURCE_DIRECT_DCACHE_CONTROL
+#endif
+
+// DMAResource API optimization 1: disable resource handle validation
+#ifdef DRIVER_PERFORMANCE
+#define HWPAL_DMARES_UMDEVXS_OPT1
+#endif
+
+// DMAResource API optimization 2: make host address first in lookup list
+#ifdef DRIVER_PERFORMANCE
+#define HWPAL_DMARES_UMDEVXS_OPT2
+#endif
+
+
+#endif // INCLUDE_GUARD_CS_HWPAL_UMDEVXS_H
+
+
+/* end of file cs_hwpal_umdevxs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs.h
new file mode 100644
index 0000000..f3d0fd8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs.h
@@ -0,0 +1,55 @@
+/* cs_intdispatch_umdevxs.h
+ *
+ * Configuration Settings for the Interrupt Dispatcher.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_INTDISPATCH_UMDEVXS_H
+#define INCLUDE_GUARD_CS_INTDISPATCH_UMDEVXS_H
+
+#include "cs_driver.h"
+#include "cs_adapter.h"
+#include "cs_intdispatch_umdevxs_ext.h"
+
+// logging level for Interrupt Dispatcher
+// Choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#undef LOG_SEVERITY_MAX
+#ifdef DRIVER_PERFORMANCE
+#define INTDISPATCH_LOG_SEVERITY  LOG_SEVERITY_CRITICAL
+#else
+#define INTDISPATCH_LOG_SEVERITY  LOG_SEVERITY_WARN
+#endif
+
+// Propagate the AIC and IRQ definitions from cs_adapter_ext.h to Int dispatcher
+#define ADAPTER_EIP202_ADD_AIC(_name,_idx,_isirq)           \
+    INTDISPATCH_AIC_RESOURCE_ADD(_name, _idx, _isirq)
+#define INTDISPATCH_AIC_RESOURCES ADAPTER_EIP202_AICS
+#define ADAPTER_EIP202_ADD_IRQ(_name,_phy,_aic,_flag,_pol)                \
+    INTDISPATCH_RESOURCE_ADD(_name,(1<<(_phy)),_aic,_flag,_pol)
+#define INTDISPATCH_RESOURCES ADAPTER_EIP202_IRQS
+
+// select which interrupts to trace
+// comment-out or set to zero to disable tracing
+#define INTDISPATCHER_TRACE_FILTER 0x00000000
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_intdispatch_umdevxs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs_ext.h
new file mode 100644
index 0000000..b3fb72a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_intdispatch_umdevxs_ext.h
@@ -0,0 +1,34 @@
+/* cs_intdispatch_umdevxs_ext.h
+ *
+ * Configuration Settings for the Interrupt Dispatcher specific for FPGA.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_INTDISPATCH_UMDEVXS_EXT_H
+#define INCLUDE_GUARD_CS_INTDISPATCH_UMDEVXS_EXT_H
+
+// Interrupt Controller device to request from Driver Framework (Device)
+#define INTDISPATCH_IC_DEVICE     "EIP201_GLOBAL"
+#define INTDISPATCH_IC_RING_DEVICE "EIP201_RING0"
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_intdispatch_umdevxs_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_list.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_list.h
new file mode 100644
index 0000000..11ca80a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_list.h
@@ -0,0 +1,53 @@
+/* cs_list.h
+ *
+ * Top-level configuration for the List module
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_LIST_H_
+#define CS_LIST_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_driver.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum supported number of the list instances
+#ifdef DRIVER_LIST_MAX_NOF_INSTANCES
+#define LIST_MAX_NOF_INSTANCES      DRIVER_LIST_MAX_NOF_INSTANCES
+#endif
+
+// Strict argument checking
+#ifndef DRIVER_PERFORMANCE
+#define LIST_STRICT_ARGS
+#endif
+
+
+#endif /* CS_LIST_H_ */
+
+
+/* end of file cs_list.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_lkm.h
new file mode 100644
index 0000000..73b5f2e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_lkm.h
@@ -0,0 +1,64 @@
+/* cs_lkm.h
+ *
+ * Top-level LKM configuration.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_LKM_H
+#define CS_LKM_H
+
+// Driver Framework top-level configuration
+#include "cs_hwpal.h"
+
+
+/*-----------------------------------------------------------------------------
+ * Configuration parameters that may not be modified!
+ */
+
+
+/*-----------------------------------------------------------------------------
+ * Configuration parameters that may be modified at top level configuration
+ */
+
+// Enables strict argument checking for input parameters
+#define LKM_STRICT_ARGS_CHECK
+
+// Choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#define LKM_LOG_SEVERITY LOG_SEVERITY_CRIT
+
+// Device name in the Device Tree Structure
+#ifdef HWPAL_PLATFORM_DEVICE_NAME
+#define LKM_PLATFORM_DEVICE_NAME    HWPAL_PLATFORM_DEVICE_NAME
+#endif
+
+// Platform-specific number of the IRQ's that will be used by the device
+#ifdef HWPAL_PLATFORM_IRQ_COUNT
+#define LKM_PLATFORM_IRQ_COUNT      HWPAL_PLATFORM_IRQ_COUNT
+#endif
+
+// Platform-specific index of the IRQ that will be used
+#ifdef HWPAL_PLATFORM_IRQ_IDX
+#define LKM_PLATFORM_IRQ_IDX        HWPAL_PLATFORM_IRQ_IDX
+#endif
+
+
+#endif // CS_LKM_H
+
+
+/* end of file cs_lkm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ringhelper.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ringhelper.h
new file mode 100644
index 0000000..a81aec9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_ringhelper.h
@@ -0,0 +1,45 @@
+/* cs_ringhelper.h
+ *
+ * Ring Helper Configuration File
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_RINGHELPER_H
+#define INCLUDE_GUARD_CS_RINGHELPER_H
+
+#include "cs_driver.h"
+
+// when enabled, all function call parameters are sanity-checked
+// comment-out to disable this code
+#ifndef DRIVER_PERFORMANCE
+#define RINGHELPER_STRICT_ARGS
+#endif
+
+// the following switch removes support for the Status Callback Function
+//#define RINGHELPER_REMOVE_STATUSFUNC
+
+// the following switch removes support for separate rings
+// use when only overlapping rings are used
+//#define RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+
+
+#endif /* Include Guard */
+
+
+/* end of file cs_ringhelper.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_sa_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_sa_builder.h
new file mode 100644
index 0000000..816b574
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_sa_builder.h
@@ -0,0 +1,117 @@
+/* cs_sa_builder.h
+ *
+ * Product-specific configuration file for the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/* DDK configuration */
+#include "cs_ddk197.h"
+
+/* Specify a specific version of the EIP-96, specify exactly one */
+#define SAB_ENABLE_CRYPTO_STANDARD
+
+/* Enable SHA2-512 algorithms */
+#define SAB_ENABLE_AUTH_SHA2_512
+
+/* Collectively enable all wireless algorithms */
+#define SAB_ENABLE_CRYPTO_WIRELESS
+
+/* Collectively enable SM4, SM3 and related algorithms */
+#define SAB_ENABLE_CRYPTO_SM4_SM3
+
+/* Enable AES-XTS */
+#define SAB_ENABLE_CRYPTO_XTS
+
+/* Enable ARCFOUR */
+#define SAB_ENABLE_CRYPTO_ARCFOUR
+
+/* Enable ChaCha20 and Poly1305 */
+#define SAB_ENABLE_CRYPTO_CHACHAPOLY
+
+/* Enable SHA3 */
+#define SAB_ENABLE_AUTH_SHA3
+
+/* Which protcol families are enabled? */
+#define SAB_ENABLE_PROTO_BASIC
+#define SAB_ENABLE_PROTO_IPSEC
+#define SAB_ENABLE_PROTO_SSLTLS
+//#define SAB_ENABLE_PROTO_MACSEC
+//#define SAB_ENABLE_PROTO_SRTP
+
+/* Which protcol-specific options are enabled? */
+#define SAB_ENABLE_IPSEC_ESP
+//#define SAB_ENABLE_IPSEC_AH
+
+/* Enable if the SA Builder must support extended use case for IPsec
+   processing */
+/* TODO: check missing header firmware_eip207_api_flow_cs.h */
+#define SAB_ENABLE_IPSEC_EXTENDED
+
+/* Enable if the SA Builder must support extended use case for DTLS
+   processing */
+//#define SAB_ENABLE_DTLS_EXTENDED
+
+/* Enable if the SA Builder must support extended use case for Basic
+   processing */
+#define SAB_ENABLE_BASIC_EXTENDED
+
+// Set this if tunnel header fields are to be copied into the transform.
+// for extended use case.
+#define SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+
+/* Enable if the SA Builder must support an engine with fixed SA records
+   (e.g. for a record cache) */
+//#define SAB_ENABLE_FIXED_RECORD_SIZE
+#define SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+
+/* Enable this if you desire to include the ARC4 state in the SA
+   record. This requires the hardware to be configured for relative
+   ARC4 state offsets */
+//#define SAB_ARC4_STATE_IN_SA
+
+#define SAB_ENABLE_384BIT_SEQMASK
+/* Enable this if the hardware supports 384-bitsequence number
+   masks. If SAB_ENABLE_256BIT_SEQMASK not also set, support 256-bit
+   masks via a work-around.*/
+#ifdef DDK_EIP197_EIP96_SEQMASK_256
+
+/* Enable this if the hardware supports 256-bit sequence
+   number masks. */
+#define SAB_ENABLE_256BIT_SEQMASK
+
+/* Enable this to use fixed offsets for sequence number masks regardless of
+   size. This only works on hardware that supports 384-bit masks. */
+#define SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+#endif
+/* IF the HW supports 1024-bit masks, the firmware needs larger offsets
+   in its large transform record */
+#ifdef DDK_EIP197_EIP96_SEQMASK_1024
+#define SAB_LARGE_TRANSFORM_OFFSET 40
+#define SAB_ENABLE_1024BIT_SEQMASK
+#endif
+
+/* Strict checking of function arguments if enabled */
+#define SAB_STRICT_ARGS_CHECK
+
+/* log level for the token builder.
+   choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT */
+#define LOG_SEVERITY_MAX LOG_SEVERITY_WARN
+
+
+/* end of file cs_sa_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_shdevxs_proxy.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_shdevxs_proxy.h
new file mode 100644
index 0000000..9a240c8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_shdevxs_proxy.h
@@ -0,0 +1,39 @@
+/* cs_shdevxs_proxy.h
+ *
+ * Configuration for user-mode proxy of Kernel Support Driver.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_SHDEVXS_PROXY_H_
+#define CS_SHDEVXS_PROXY_H_
+#include "cs_shdevxs_proxy.h"
+
+#define SHDEVXS_IRQ_COUNT 31
+
+#define SHDEVXS_PROXY_MAX_DMA_BANKS 2
+
+#define SHDEVXS_PROXY_IRQ_TIMEOUT_MS 1000
+
+#define SHDEVXS_PROXY_REMOVE_IRQ_CLEAR
+#define SHDEVXS_PROXY_REMOVE_RC
+#define SHDEVXS_PROXY_REMOVE_TEST
+#endif /* CS_SHDEVXS_PROXY_H_ */
+
+
+/* end of file cs_shdevxs_proxy.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_systemtestconfig.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_systemtestconfig.h
new file mode 100644
index 0000000..01594e1
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_systemtestconfig.h
@@ -0,0 +1,28 @@
+/* cs_systemtestconfig.h
+ *
+ * Selects the system test configuration through a single define.
+ * The configuration file cs_driver.h includes this file to get
+ * this definition only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// vary the number at the end
+#define SYSTEMTEST_CONFIGURATION_C0
+
+/* end of file cs_systemtestconfig.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_token_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_token_builder.h
new file mode 100644
index 0000000..ec1dacf
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_token_builder.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL */
+/* cs_token_builder.h
+ *
+ * Product-specific configuration file for the token builder.
+ */
+
+/*****************************************************************************
+ * Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+
+/* Uncomment this option if the EIP-96 does not use an input packet pointer.
+ *  This is the case when it is used in a system in which packet data is fetched
+ *  outside the control of the EIP-96. Whether this setting is needed depends
+ *  on the hardware environment in which the EIP-96 is integrated.
+ */
+#define TKB_NO_INPUT_PACKET_POINTER
+
+/* Uncomment this option if context reuse must be auto-detected. This
+ *  is only supported in EIP-96 HW2.1 and higher.
+ */
+#define TKB_AUTODETECT_CONTEXT_REUSE
+
+
+#define TKB_ENABLE_CRYPTO_WIRELESS
+#define TKB_ENABLE_CRYPTO_XTS
+#define TKB_ENABLE_CRYPTO_CHACHAPOLY
+
+
+/* Which protocol families are enabled? */
+#define TKB_ENABLE_PROTO_BASIC
+#define TKB_ENABLE_PROTO_IPSEC
+#define TKB_ENABLE_PROTO_SSLTLS
+/* #define TKB_ENABLE_PROTO_MACSEC */
+/* #define TKB_ENABLE_PROTO_SRTP */
+
+/* Which protocol-specific options are enabled? */
+#define TKB_ENABLE_IPSEC_ESP
+/* #define TKB_ENABLE_IPSEC_AH */
+
+/* Strict checking of function arguments if enabled */
+#define TKB_STRICT_ARGS_CHECK
+
+#define TKB_ENABLE_CRYPTO_WIRELESS
+
+/* log level for the token builder.
+ *  choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+ */
+#define LOG_SEVERITY_MAX LOG_SEVERITY_WARN
+
+/* end of file cs_token_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_umdevxsproxy.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_umdevxsproxy.h
new file mode 100644
index 0000000..6893d7d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/configs/cs_umdevxsproxy.h
@@ -0,0 +1,43 @@
+/* cs_umdevxsproxy.h
+ *
+ * Configuration options for UMDevXS Proxy Library.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CS_UMDEVXSPROXY_H
+#define INCLUDE_GUARD_CS_UMDEVXSPROXY_H
+
+//#define UMDEVXSPROXY_REMOVE_SMBUF
+#define UMDEVXSPROXY_REMOVE_SMBUF_ATTACH
+#define UMDEVXSPROXY_REMOVE_SMBUF_COMMIT
+#define UMDEVXSPROXY_REMOVE_DEVICE_FIND
+#define UMDEVXSPROXY_REMOVE_DEVICE_ENUM
+#define UMDEVXSPROXY_REMOVE_DEVICE_UNMAP
+#define UMDEVXSPROXY_REMOVE_PCICFG
+
+//#define UMDEVXSPROXY_REMOVE_INTERRUPT
+
+#define UMDEVXSPROXY_NODE_NAME "/dev/driver_197_ks_c"
+
+
+#endif /* INCLUDE_GUARD_CS_UMDEVXSPROXY_H */
+
+
+/* end of file cs_umdevxsproxy.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_device_generic.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_device_generic.h
new file mode 100644
index 0000000..1f6651b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_device_generic.h
@@ -0,0 +1,43 @@
+/* c_device_generic.h
+ *
+ * This is the default configuration file for the generic Driver Framework
+ * implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// Top-level Hardware platform configuration
+#include "cs_hwpal.h"
+
+// Enables strict argument checking for input parameters
+//#define HWPAL_STRICT_ARGS_CHECK
+
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_INFO
+#endif
+
+#ifndef HWPAL_MAX_DEVICE_NAME_LENGTH
+#error "HWPAL_MAX_DEVICE_NAME_LENGTH undefined"
+#endif
+
+// Some magic number for device data validation
+//#define HWPAL_DEVICE_MAGIC   0xBABADEDAUL
+
+
+/* end of file c_device_generic.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_dmares_gen.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_dmares_gen.h
new file mode 100644
index 0000000..fd36182
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/c_dmares_gen.h
@@ -0,0 +1,76 @@
+/* c_dmares_gen.h
+ *
+ * Default configuration for generic Driver Framework DMAResource API
+ * implementation.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_DMARES_GEN_H_
+#define C_DMARES_GEN_H_
+
+
+/*----------------------------------------------------------------
+ * get configuration settings from product config file
+ */
+#include "cs_hwpal.h"
+
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_INFO
+#endif
+
+#ifdef HWPAL_DMARESOURCE_BANKS_ENABLE
+#ifndef HWPAL_DMARESOURCE_BANKS
+#error "Expected HWPAL_DMARESOURCE_BANKS defined by cs_hwpal.h"
+#endif
+#endif // HWPAL_DMARESOURCE_BANKS_ENABLE
+
+// Enable use of UMDevXS device
+#ifdef HWPAL_USE_UMDEVXS_DEVICE
+#define HWPAL_DMARESOURCE_USE_UMDEVXS_DEVICE
+#endif // HWPAL_USE_UMDEVXS_DEVICE
+
+/*----------------------------------------------------------------
+ * Other configuration parameters that can be set in a top level
+ * configuration
+ */
+
+// Enables DMA resources banks so that different memory regions can be used
+// for DMA buffer allocation
+//#define HWPAL_DMARESOURCE_BANKS_ENABLE
+
+#ifndef HWPAL_DMARESOURCE_DMA_ALIGNMENT_BYTE_COUNT
+#ifdef HWPAL_DMARESOURCE_64BIT
+// Default 8 bytes (64 bits) address alignment
+#define HWPAL_DMARESOURCE_DMA_ALIGNMENT_BYTE_COUNT      8
+#else
+// Default 4 bytes (32 bits) address alignment
+#define HWPAL_DMARESOURCE_DMA_ALIGNMENT_BYTE_COUNT      4
+#endif
+#endif
+
+// When defined enables strict argument checking
+//#define HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+
+
+#endif // C_DMARES_GEN_H_
+
+
+/* end of file c_dmares_gen.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_internal.h
new file mode 100644
index 0000000..667a11c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_internal.h
@@ -0,0 +1,224 @@
+/* device_internal.h
+ *
+ * Driver Framework Device Internal interface.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DEVICE_INTERNAL_H_
+#define DEVICE_INTERNAL_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_device_generic.h"
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+// Driver Framework Device Platform interface
+#include "device_platform.h"        // Device_Platform_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Global administration data
+typedef struct
+{
+    // Initialization flag
+    bool fInitialized;
+
+    Device_Platform_Global_t Platform; // platform-specific global data
+} Device_Global_Admin_t;
+
+// Internal statically configured device administration data
+typedef struct
+{
+    const char * DevName;
+    unsigned int DeviceNr;
+    unsigned int FirstOfs;
+    unsigned int LastOfs;
+    unsigned int Flags; // swapping, tracing
+} Device_Admin_Static_t;
+
+// Internal device administration data
+typedef struct
+{
+    char * DevName;
+    unsigned int DeviceNr;
+    unsigned int FirstOfs;
+    unsigned int LastOfs;
+    unsigned int Flags; // swapping, tracing
+
+#ifdef HWPAL_DEVICE_MAGIC
+    unsigned int Magic;
+#endif
+
+    Device_Platform_t Platform; // platform-specific device data
+
+    unsigned int DeviceId; // index in the device list
+
+} Device_Admin_t;
+
+#define HWPAL_DEVICE_ADD(_name, _devnr, _firstofs, _lastofs, _flags) \
+                        {_name, _devnr, _firstofs, _lastofs, _flags}
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Static_Count_Get
+ *
+ * Returns number of statically configured devices in the HWPAL_DEVICES device
+ * list.
+ *
+ */
+unsigned int
+Device_Internal_Static_Count_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Count_Get
+ *
+ * Returns number of maximum supported devices in the device list.
+ *
+ */
+unsigned int
+Device_Internal_Count_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Static_Get
+ *
+ * Returns pointer to the memory location where the statically configured
+ * device list is stored.
+ *
+ */
+const Device_Admin_Static_t *
+Device_Internal_Admin_Static_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Get
+ *
+ * Returns pointer to the memory location where the device list is stored.
+ *
+ */
+Device_Admin_t **
+Device_Internal_Admin_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Admin_Global_Get
+ *
+ * Returns pointer to the memory location where the global device
+ * administration data is stored.
+ *
+ */
+Device_Global_Admin_t *
+Device_Internal_Admin_Global_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Alloc
+ *
+ * Returns a pointer to a newly allocated block ByteCount bytes long, or a null
+ * pointer if the block could not be allocated.
+ *
+ */
+void *
+Device_Internal_Alloc(
+        unsigned int ByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Free
+ *
+ * Deallocates the block of memory pointed at by Ptr.
+ *
+ */
+void
+Device_Internal_Free(
+        void * Ptr);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_Initialize
+ *
+ * See Device_Initialize() description.
+ *
+ */
+int
+Device_Internal_Initialize(
+        void * CustomInitData_p);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Internal_UnInitialize
+ *
+ * See Device_UnInitialize() description.
+ *
+ */
+void
+Device_Internal_UnInitialize(void);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_Find
+ *
+ * See Device_Find() description.
+ *
+ * Index (input)
+ *      Device  index in the device list.
+ *
+ */
+Device_Handle_t
+Device_Internal_Find(
+        const char * DeviceName_p,
+        const unsigned int Index);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_Internal_GetIndex
+ *
+ * See Device_GetIndex() description.
+ *
+ */
+int
+Device_Internal_GetIndex(
+        const Device_Handle_t Device);
+
+
+#endif // DEVICE_INTERNAL_H_
+
+
+/* end of file device_internal.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_mgmt.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_mgmt.h
new file mode 100644
index 0000000..0eecf52
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_mgmt.h
@@ -0,0 +1,249 @@
+/* device_mgmt.h
+ *
+ * Driver Framework, Device API, Management functions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DEVICE_MGMT_H
+#define INCLUDE_GUARD_DEVICE_MGMT_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Device API API
+#include "device_types.h"   // Device_Handle_t, Device_Reference_t
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"     // bool, uint32_t, inline
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Device_Initialize
+ *
+ * This function must be called exactly once to initialize the Device
+ * implementation before any other API function may be used.
+ *
+ * CustomInitData_p
+ *     This anonymous parameter can be used to pass information from the caller
+ *     to the driver framework implementation.
+ *
+ * Return Value
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+Device_Initialize(
+        void * CustomInitData_p);
+
+
+/*----------------------------------------------------------------------------
+ * Device_UnInitialize
+ *
+ * This function can be called to shut down the Device implementation. The
+ * caller must make sure none of the other API functions are called after or
+ * during the invocation of this UnInitialize function. After this call
+ * returns the API state is back in "uninitialized" and the Device_Initialize
+ * function may be called anew.
+ *
+ * Return Value
+ *     None
+ */
+void
+Device_UnInitialize(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Find
+ *
+ * This function must be used to retrieve a handle for a certain device that
+ * is identified by a string. The exact strings supported is implementation
+ * specific and will differ from product to product.
+ * Note that this function may be called more than once to retrieve the same
+ * handle for the same device.
+ *
+ * DeviceName_p (input)
+ *     Pointer to the (zero-terminated) string that represents the device.
+ *
+ * Return Value
+ *     NULL    No device found with requested
+ *     !NULL   Device handle that can be used in the Device API
+ */
+Device_Handle_t
+Device_Find(
+        const char * szDeviceName_p);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetReference
+ *
+ * This function can be used to obtain the implementation-specific device
+ * reference
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find for which
+ *     the reference must be obtained.
+ *
+ * Data_p (output)
+ *     Pointer to memory location where device data will be stored.
+ *     If not used then set to NULL.
+ *
+ * Return Value
+ *     NULL    No reference found for the requested device instance
+ *     !NULL   Device reference
+ */
+Device_Reference_t
+Device_GetReference(
+        const Device_Handle_t Device,
+        Device_Data_t * const Data_p);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetName
+ *
+ * This function returns the device name for the provided index.
+ *
+ * Index (input)
+ *     Device index in the device list for which the name must be obtained
+ *
+ * Return Value
+ *     NULL    No valid device found in the device list at the provided index
+ *     !NULL   Device name
+ */
+char *
+Device_GetName(
+        const unsigned int Index);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetIndex
+ *
+ * This function returns the device index for the provided device handle.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find for which
+ *     the reference must be obtained.
+ *
+ * Return Value
+ *     >= 0 Device index
+ *     <0   Error
+ */
+int
+Device_GetIndex(
+        const Device_Handle_t Device);
+
+
+/*-----------------------------------------------------------------------------
+ * Device_GetCount
+ *
+ * This function returns the number of devices present in the device list.
+ *
+ * Return Value
+ *     Device count.
+ */
+unsigned int
+Device_GetCount(void);
+
+
+/*----------------------------------------------------------------------------
+ * Device_GetProperties
+ *
+ * Retrieve the properties of a device, the same as used in Device_Add
+ *
+ * Index (input)
+ *     Device index indicating which device to read the properties from.
+ *
+ * Props_p (output)
+ *     Pointer to memory location where device properties are stored,
+ *     may not be NULL.
+ *
+ * fValid_p (output)
+ *     Flag indicating if there is a valid device at this index.
+ *
+ * Return Value
+ *     0    success
+ *     -1   failure
+ */
+int
+Device_GetProperties(
+        const unsigned int Index,
+        Device_Properties_t * const Props_p,
+        bool * const fValid_p);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Add
+ *
+ * Adds a new device to the device list.
+ *
+ * This function must be called before any other function can reference
+ * this device.
+ *
+ * Index (input)
+ *     Device index where the device must be added in the device list
+ *
+ * Props_p (input)
+ *     Pointer to memory location where device properties are stored,
+ *     may not be NULL
+ *
+ * Return Value
+ *     0    success
+ *     -1   failure
+ */
+int
+Device_Add(
+        const unsigned int Index,
+        const Device_Properties_t * const Props_p);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Remove
+ *
+ * Removes device from the device list at the requested index,
+ * the device must be previously added either statically or via a call
+ * to the Device_Add() function.
+ *
+ * This function must be called when no other driver function can reference
+ * this device.
+ *
+ * Index (input)
+ *     Device index where the device must be added in the device list
+ *
+ * Return Value
+ *     0    success
+ *     -1   failure
+ */
+int
+Device_Remove(
+        const unsigned int Index);
+
+
+#endif /* Include Guard */
+
+
+/* end of file device_mgmt.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_rw.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_rw.h
new file mode 100644
index 0000000..f22bc18
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_rw.h
@@ -0,0 +1,215 @@
+/* device_rw.h
+ *
+ * Driver Framework, Device API, Read/Write functions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DEVICE_RW_H
+#define INCLUDE_GUARD_DEVICE_RW_H
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"     // uint32_t, inline
+
+// Driver Framework Device API
+#include "device_types.h"   // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Device_Read32
+ *
+ * This function can be used to read one static 32bit resource inside a device
+ * (typically a register or memory location). Since reading registers can have
+ * side effects, the implementation must guarantee that the resource will be
+ * read only once and no neighboring resources will be accessed.
+ *
+ * If required (decided based on internal configuration), on the fly endianness
+ * swapping of the value read will be performed before it is returned to the
+ * caller.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find.
+ *
+ * ByteOffset (input)
+ *     The byte offset within the device for the resource to read.
+ *
+ * Return Value
+ *     The value read.
+ *
+ * When the Device or Offset parameters are invalid, or a read error occurs,
+ * the implementation will return an unspecified value.
+ */
+uint32_t
+Device_Read32(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Read32Check
+ *
+ * This function can be used to read one static 32-bit resource inside a device
+ * (typically a register or memory location). Since reading registers can have
+ * side effects, the implementation must guarantee that the resource will be
+ * read only once and no neighboring resources will be accessed.
+ *
+ * If required (decided based on internal configuration), on the fly endianess
+ * swapping of the value read will be performed before it is returned to the
+ * caller.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find.
+ *
+ * ByteOffset (input)
+ *     The byte offset within the device for the resource to read.
+ *
+ * Value_p (output)
+ *     The 32-bit value read from the register.
+ *
+ * Return Value
+ *     0 for success, non-zero value for read error.
+ *
+ * When the Device or Offset parameters are invalid, or a read error occurs,
+ * the implementation will return an unspecified value.
+ */
+int
+Device_Read32Check(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset,
+        uint32_t * const Value_p);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Write32
+ *
+ * This function can be used to write one static 32bit resource inside a
+ * device (typically a register or memory location). Since writing registers
+ * can have side effects, the implementation must guarantee that the resource
+ * will be written exactly once and no neighboring resources will be
+ * accessed.
+ *
+ * If required (decided based on internal configuration), on the fly endianness
+ * swapping of the value to be written will be performed.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find.
+ *
+ * ByteOffset (input)
+ *     The byte offset within the device for the resource to write.
+ *
+ * Value (input)
+ *     The 32bit value to write.
+ *
+ * Return Value
+ *     0 for success, non-zero value for write error.
+ *
+ * The write can only be successful when the Device and ByteOffset parameters
+ * are valid.
+ */
+int
+Device_Write32(
+        const Device_Handle_t Device,
+        const unsigned int ByteOffset,
+        const uint32_t Value);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Read32Array
+ *
+ * This function perform the same task as Device_Read32 for an array of
+ * consecutive 32bit words, allowing the implementation to use a more optimal
+ * burst-read (if available).
+ *
+ * See Device_Read32 for pre-conditions and a more detailed description.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find.
+ *
+ * StartByteOffset (input)
+ *     Byte offset of the first resource to read.
+ *     This value is incremented by 4 for each following resource.
+ *
+ * MemoryDst_p (output)
+ *     Pointer to the memory where the retrieved words will be stored.
+ *
+ * Count (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Return Value
+ *     0 for success, non-zero value for read error.
+ *
+ * When the Device or Offset parameters are invalid, or a read error occurs,
+ * the implementation will return unspecified array values.
+ */
+int
+Device_Read32Array(
+        const Device_Handle_t Device,
+        const unsigned int StartByteOffset,
+        uint32_t * MemoryDst_p,
+        const int Count);
+
+
+/*----------------------------------------------------------------------------
+ * Device_Write32Array
+ *
+ * This function perform the same task as Device_Write32 for an array of
+ * consecutive 32bit words, allowing the implementation to use a more optimal
+ * burst-write (if available).
+ *
+ * See Device_Write32 for pre-conditions and a more detailed description.
+ *
+ * Device (input)
+ *     Handle for the device instance as returned by Device_Find.
+ *
+ * StartByteOffset (input)
+ *     Byte offset of the first resource to write.
+ *     This value is incremented by 4 for each following resource.
+ *
+ * MemorySrc_p (input)
+ *     Pointer to the memory where the values to be written are located.
+ *
+ * Count (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Return Value
+ *     0 for success, non-zero value for write error.
+ */
+int
+Device_Write32Array(
+        const Device_Handle_t Device,
+        const unsigned int StartByteOffset,
+        const uint32_t * MemorySrc_p,
+        const int Count);
+
+
+/* The defines below specify the possible return codes of the implementations
+   of these API functions */
+
+/* Device error return code for invalid parameter */
+#define DEVICE_RW_PARAM_ERROR 0x00000010
+
+/* Device error return code for a not initialized situation */
+#define DEVICE_NOT_INITIALIZED_ERROR 0xEEEEEEEE
+
+#endif /* Include Guard */
+
+/* end of file device_rw.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_swap.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_swap.h
new file mode 100644
index 0000000..2334cbe
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_swap.h
@@ -0,0 +1,59 @@
+/* device_swap.h
+ *
+ * Driver Framework, Device API, Swap-Endianness function
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DEVICE_SWAP_H
+#define INCLUDE_GUARD_DEVICE_SWAP_H
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"     // uint32_t, inline
+
+/*----------------------------------------------------------------------------
+ * Device_SwapEndian32
+ *
+ * This function can be used to swap the byte order of a 32bit integer. The
+ * implementation could use custom CPU instructions, if available.
+ */
+static inline uint32_t
+Device_SwapEndian32(
+        const uint32_t Value)
+{
+#ifdef DEVICE_SWAP_SAFE
+    return (((Value & 0x000000FFU) << 24) |
+            ((Value & 0x0000FF00U) <<  8) |
+            ((Value & 0x00FF0000U) >>  8) |
+            ((Value & 0xFF000000U) >> 24));
+#else
+    // reduces typically unneeded AND operations
+    return ((Value << 24) |
+            ((Value & 0x0000FF00U) <<  8) |
+            ((Value & 0x00FF0000U) >>  8) |
+            (Value >> 24));
+#endif
+}
+
+#endif /* Include Guard */
+
+/* end of file device_swap.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_types.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_types.h
new file mode 100644
index 0000000..88c57fb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/device_types.h
@@ -0,0 +1,99 @@
+/* device_types.h
+ *
+ * Driver Framework, Device API, Type Definitions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DEVICE_TYPES_H
+#define INCLUDE_GUARD_DEVICE_TYPES_H
+
+/*----------------------------------------------------------------------------
+ * Device_Handle_t
+ *
+ * This handle represents a device, typically one hardware block instance.
+ *
+ * The Device API can access the static device resources (registers and RAM
+ * inside the device) using offsets inside the device. This abstracts memory
+ * map knowledge and simplifies device instantiation.
+ *
+ * Each device has its own configuration, including the endianness swapping
+ * need for the words transferred. Endianness swapping can thus be performed
+ * on the fly and transparent to the caller.
+ *
+ * The details of the handle are implementation specific and must not be
+ * relied on, with one exception: NULL is guaranteed to be a non-existing
+ * handle.
+ */
+
+typedef void * Device_Handle_t;
+
+
+/*----------------------------------------------------------------------------
+ * Device_Reference_t
+ *
+ * This is an implementation-specific reference for the device. It can
+ * be passed from the implementation of the Device API to other modules
+ * for use, for example, with OS services that require such a reference.
+ *
+ * The details of the handle are implementation specific and must not be
+ * relied on, with one exception: NULL is guaranteed to be a non-existing
+ * handle.
+ */
+typedef void * Device_Reference_t;
+
+
+/*----------------------------------------------------------------------------
+ * Device_Data_t
+ *
+ * This is an implementation-specific reference for the device. It can
+ * be passed from the implementation of the Device API to other modules
+ * for use, for example, with OS services that require such a reference.
+ */
+typedef struct
+{
+    // Physical address of the device mapped in memory
+    void * PhysAddr;
+
+} Device_Data_t;
+
+
+// Device properties structure
+typedef struct
+{
+    // Device name
+    char * Name_p;
+
+    // Device offset range inside system memory map
+    unsigned int StartByteOffset;
+    unsigned int LastByteOffset;
+
+    // Implementation specific device flags
+    char Flags;
+
+} Device_Properties_t;
+
+
+#endif /* Include Guard */
+
+
+/* end of file device_types.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_gen.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_gen.h
new file mode 100644
index 0000000..4dc9506
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_gen.h
@@ -0,0 +1,86 @@
+/* dmares_gen.h
+ *
+ * Declare functions exported by "dmares_gen.c" that implements large parts
+ * of the DMAResource API. The exported functions are to be used by module(s)
+ * that implement the remaining parts of the DMAResource API.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DMARES_GEN_H_
+#define DMARES_GEN_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+// Driver Framework DMAResource Types API
+#include "dmares_types.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_IsSaneInput
+ */
+bool
+DMAResourceLib_IsSaneInput(
+        const DMAResource_AddrPair_t * AddrPair_p,
+        const char * const AllocatorRef_p,
+        const DMAResource_Properties_t * Props_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_AlignForSize
+ */
+unsigned int
+DMAResourceLib_AlignForSize(
+        const unsigned int ByteCount,
+        const unsigned int AlignTo);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_AlignForAddress
+ */
+unsigned int
+DMAResourceLib_AlignForAddress(
+        const unsigned int ByteCount,
+        const unsigned int AlignTo);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResourceLib_LookupDomain
+ */
+DMAResource_AddrPair_t *
+DMAResourceLib_LookupDomain(
+        const DMAResource_Record_t * Rec_p,
+        const DMAResource_AddrDomain_t Domain);
+
+
+#endif // DMARES_GEN_H_
+
+
+/* end of file dmares_gen.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_hwpal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_hwpal.h
new file mode 100644
index 0000000..e94ee77
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/dmares_hwpal.h
@@ -0,0 +1,186 @@
+/* dmares_hwpal.h
+ *
+ * HW and OS abstraction API
+ * for the Driver Framework DMAResource API implementation
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DMARES_HWPAL_H_
+#define DMARES_HWPAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t, NULL, inline, bool
+
+// Driver Framework DMAResource Types API
+#include "dmares_types.h"
+
+// Driver Framework C Library abstraction API
+#include "clib.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Dynamic flag cannot be mixed with any other HWPAL_DMARESOURCE_BANK_* flags
+#define HWPAL_DMARESOURCE_BANK_DYNAMIC                  0
+
+// Maximum number of supported dynamic DMA banks
+#define HWPAL_DMARESOURCE_MAX_NOF_BANKS                 30
+
+// Static flags can be mixed with each other for the same bank
+#define HWPAL_DMARESOURCE_BANK_STATIC                   (HWPAL_DMARESOURCE_MAX_NOF_BANKS + 1)
+#define HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR        (HWPAL_DMARESOURCE_MAX_NOF_BANKS + 3)
+
+#define HWPAL_DMARESOURCE_BANK_STATIC_LAST              HWPAL_DMARESOURCE_BANK_STATIC_FIXED_ADDR
+
+
+// Internal DMAResource_Properties_t extension
+typedef struct
+{
+    void * Addr;
+    unsigned int BankType;
+} HWPAL_DMAResource_Properties_Ext_t;
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MaxAlignment_Get
+ */
+unsigned int
+HWPAL_DMAResource_MaxAlignment_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_DCache_Alignment_Get
+ */
+unsigned int
+HWPAL_DMAResource_DCache_Alignment_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MemAlloc
+ */
+void *
+HWPAL_DMAResource_MemAlloc(
+        size_t ByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_MemFree
+ */
+void
+HWPAL_DMAResource_MemFree(
+        void * Buf_p);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Alloc
+ */
+void *
+HWPAL_DMAResource_Lock_Alloc(void);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Free
+ */
+void
+HWPAL_DMAResource_Lock_Free(void * Lock_p);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Acquire
+ */
+void
+HWPAL_DMAResource_Lock_Acquire(
+        void * Lock_p,
+        unsigned long * Flags);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Lock_Release
+ */
+void
+HWPAL_DMAResource_Lock_Release(
+        void * Lock_p,
+        unsigned long * Flags);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Alloc
+ */
+int
+HWPAL_DMAResource_Alloc(
+        const DMAResource_Properties_t RequestedProperties,
+        const HWPAL_DMAResource_Properties_Ext_t RequestedPropertiesExt,
+        DMAResource_AddrPair_t * const AddrPair_p,
+        DMAResource_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Release
+ */
+int
+HWPAL_DMAResource_Release(
+        const DMAResource_Handle_t Handle);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Init
+ */
+bool
+HWPAL_DMAResource_Init(void);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_UnInit
+ */
+void
+HWPAL_DMAResource_UnInit(void);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_CheckAndRegister
+ */
+int
+HWPAL_DMAResource_CheckAndRegister(
+        const DMAResource_Properties_t RequestedProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        const char AllocatorRef,
+        DMAResource_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * HWPAL_DMAResource_Record_Update
+ */
+int
+HWPAL_DMAResource_Record_Update(
+        const int Identifier,
+        DMAResource_Record_t * const Rec_p);
+
+
+#endif // DMARES_HWPAL_H_
+
+
+/* end of file dmares_hwpal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_device_lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_device_lkm.h
new file mode 100644
index 0000000..fb99c32
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_device_lkm.h
@@ -0,0 +1,146 @@
+/* c_device_lkm.h
+ *
+ * Configuration Handling for Driver Framework Device API implementation.
+ * A build-level configuration file is included and sanity-checked.
+ * Do not edit this file. Edit cs_hwpal_lkm.h instead.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------
+ * get configuration settings from product config file
+ */
+
+// Top-level Hardware platform configuration
+#include "cs_hwpal_lkm.h"
+
+
+// Enables strict argument checking for input parameters
+//#define HWPAL_STRICT_ARGS_CHECK
+
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_INFO
+#endif
+
+#ifndef HWPAL_MAX_DEVICE_NAME_LENGTH
+#error "HWPAL_MAX_DEVICE_NAME_LENGTH undefined"
+#endif
+
+#ifndef HWPAL_DEVICES
+#error " HWPAL_DEVICES undefined"
+#endif
+
+// Device driver name used for looking up the device and reporting
+#ifndef HWPAL_DRIVER_NAME
+#define HWPAL_DRIVER_NAME "Security"
+#endif
+
+/*----------------------------------------------------------------
+ * Other configuration parameters that can be set in a top level
+ * configuration
+ */
+
+/* HWPAL_DEVICE_ID
+ *
+ * Device identification required for implementation of Device API
+ */
+
+/* HWPAL_VENDOR_ID
+ *
+ * Device vendor identification required for implementation of Device API
+ */
+
+/* HWPAL_DEVICE_RESOURCE_ID
+ *
+ * Device resource identification required for implementation of Device API
+ */
+#ifndef HWPAL_DEVICE_RESOURCE_ID
+#define HWPAL_DEVICE_RESOURCE_ID        0
+#endif
+
+/* HWPAL_DEVICE_RESOURCE_BYTE_COUNT
+ *
+ * Device resource size (in bytes), if 0 then the resource maximum size will be
+ * determined and used.
+ *
+ */
+#ifndef HWPAL_DEVICE_RESOURCE_BYTE_COUNT
+#define HWPAL_DEVICE_RESOURCE_BYTE_COUNT        0 // Use the entire resource
+#endif
+
+/* HWPAL_REMAP_ADDRESSES
+ *
+ * Macro that can be used to remap a device static resource offset
+ * (a relative address) to another address
+ *
+ * Example:
+ * #define HWPAL_REMAP_ADDRESSES     HWPAL_REMAP_ONE(0x71004, 0x71200);
+ *
+ */
+
+/* HWPAL_DEVICE_MAGIC
+ *
+ * Optional magic number used to validate device administration data
+ */
+
+/* HWPAL_DEVICE_DIRECT_MEMIO
+ *
+ * Enable this parameter in order to use the direct memory I/O
+ * operations bypassing the Linux kernel memory I/O API
+ */
+
+/* HWPAL_PLATFORM_IRQ_IDX
+ *
+ * Platform-specific index of the IRQ that will be used.
+ *
+ */
+#ifndef HWPAL_PLATFORM_IRQ_IDX
+#define HWPAL_PLATFORM_IRQ_IDX 0
+#endif
+
+/* HWPAL_USE_UMDEVXS_DEVICE
+ *
+ * Use external Linux kernel device data structure provided by the kernel
+ * after instantiating the device driver in the kernel.
+ *
+ */
+//#define HWPAL_USE_UMDEVXS_DEVICE
+
+/* HWPAL_DEVICE_READ_DELAY_US
+ *
+ * Device_Read32() function will busy wait for the specified number
+ * of microseconds before actually performing the read operation.
+ *
+ * Note: This is a workaround for posted-writes implementation of
+ *       the MMIO register slave interface
+ *       (when too fast write-read sequence does not work)
+ *
+ *
+ */
+//#define HWPAL_DEVICE_READ_DELAY_US    100
+
+
+/* HWPAL_DEVICE_USE_RPM
+ *
+ * Enables use of runtime power management
+ */
+//#define HWPAL_DEVICE_USE_RPM
+
+
+/* end of file c_device_lkm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_dmares_lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_dmares_lkm.h
new file mode 100644
index 0000000..19c94f1
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_dmares_lkm.h
@@ -0,0 +1,125 @@
+/* c_dmares_lkm.h
+ *
+ * Configuration Handling for Driver Framework DMAResource API implementation.
+ * A build-level configuration file is included and sanity-checked.
+ * Do not edit this file. Edit cs_hwpal_lkm.h instead.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_DMARES_LKM_H_
+#define C_DMARES_LKM_H_
+
+
+/*----------------------------------------------------------------
+ * get configuration settings from product config file
+ */
+
+// Top-level Hardware platform configuration
+#include "cs_hwpal_lkm.h"
+
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_INFO
+#endif
+
+#ifndef HWPAL_DMA_NRESOURCES
+#error "Expected HWPAL_DMA_NRESOURCES defined by cs_hwpal_lkm.h"
+#endif
+
+#if HWPAL_DMA_NRESOURCES < 8
+#error "HWPAL_DMA_NRESOURCES too small"
+#endif
+
+
+/*----------------------------------------------------------------
+ * Other configuration parameters that can be set in a top level
+ * configuration
+ */
+
+/* HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT
+ *
+ * Enable this parameter in order to use the coherent Linux DMA mappings,
+ * all allocated DMA buffers will be cache-coherent.
+ */
+
+/* HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL
+ *
+ * Enable this parameter in order to use the minimal Linux DMA API,
+ * this will also make the Linux Kernel to perform less sanity checks
+ * on the provided DMA buffers
+ */
+
+#if defined(HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT) && \
+    defined(HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL)
+#error "Error: Cannot define both HWPAL_DMARESOURCE_ALLOC_CACHE_COHERENT and" \
+       " HWPAL_DMARESOURCE_MINIMUM_CACHE_CONTROL at the same time"
+#endif
+
+// Note: D-cache line size,
+//       this can be customized for some platforms to other value.
+//       The implementation will ask OS for this parameter if not defined.
+#if 0
+#ifndef HWPAL_DMARESOURCE_DCACHE_LINE_SIZE
+#ifdef HWPAL_64BIT_HOST
+// Note: D-cache line size,
+//       this can be customized for some platforms to other value
+#define HWPAL_DMARESOURCE_DCACHE_LINE_SIZE          64 // 64 bytes
+#else
+#define HWPAL_DMARESOURCE_DCACHE_LINE_SIZE          32 // 32 bytes
+#endif
+#endif // !HWPAL_DMARESOURCE_DCACHE_LINE_SIZE
+#endif
+
+/* HWPAL_DMARESOURCE_BANK_STATIC_OFFSET
+ *
+ * Internal memory offset as seen by the CPU but not by the EIP HW device,
+ * used for static DMA banks
+ */
+#ifndef HWPAL_DMARESOURCE_BANK_STATIC_OFFSET
+#define HWPAL_DMARESOURCE_BANK_STATIC_OFFSET    0
+#endif
+
+/* HWPAL_DMARESOURCE_UNCACHED_MAPPING
+ *
+ * When defined enables use of ioremap_cache for mapping memory as non-cached
+ * used for static DMA banks
+ */
+//#define HWPAL_DMARESOURCE_UNCACHED_MAPPING
+
+/* HWPAL_DMARESOURCE_ADDR_MASK
+ *
+ * DMA address mask, e.g. how many address bits the device can use
+ */
+#ifndef HWPAL_DMARESOURCE_ADDR_MASK
+#ifdef HWPAL_DMARESOURCE_64BIT
+#define HWPAL_DMARESOURCE_ADDR_MASK 0xffffffffffL
+#else
+#define HWPAL_DMARESOURCE_ADDR_MASK 0xffffffff
+#endif
+#endif
+
+// When defined enables strict argument checking
+//#define HWPAL_DMARESOURCE_STRICT_ARGS_CHECKS
+
+
+#endif // C_DMARES_LKM_H_
+
+
+/* end of file c_dmares_lkm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_lkm.h
new file mode 100644
index 0000000..354266a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/c_lkm.h
@@ -0,0 +1,87 @@
+/* c_lkm.h
+ *
+ * Configuration Handling for the LKM implementation.
+ * A build-level configuration file is included and sanity-checked.
+ * Do not edit this file. Edit cs_lkm.h instead.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------
+ * get configuration settings from product config file
+ */
+
+// Top-level Hardware platform configuration
+#include "cs_lkm.h"
+
+
+// Enables strict argument checking for input parameters
+//#define LKM_STRICT_ARGS_CHECK
+
+// choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT
+#ifndef LKM_LOG_SEVERITY
+#define LKM_LOG_SEVERITY LOG_SEVERITY_INFO
+#endif
+
+/* LKM_DEVICE_ID
+ *
+ * PCI device identification required for implementation of Device API
+ */
+//#define LKM_DEVICE_ID             0x6018
+
+/* LKM_VENDOR_ID
+ *
+ * PCI device vendor identification required for implementation of Device API
+ */
+//#define LKM_VENDOR_ID             0x10EE
+
+/* LKM_LOG_PREFIX
+ *
+ * Logging prefix that precedes each trace line in log
+ */
+#ifndef LKM_LOG_PREFIX
+#define LKM_LOG_PREFIX                  ""
+#endif
+
+/* LKM_PLATFORM_DEVICE_NAME
+ *
+ * Platform-specific device name that can be used for looking up
+ * device properties
+ */
+//#define LKM_PLATFORM_DEVICE_NAME      "Unknown"
+
+/* LKM_PLATFORM_IRQ_COUNT
+ *
+ * Platform-specific number of the IRQ's that will be used by the device.
+ *
+ */
+#ifndef LKM_PLATFORM_IRQ_COUNT
+#define LKM_PLATFORM_IRQ_COUNT          1
+#endif
+
+/* LKM_PLATFORM_IRQ_IDX
+ *
+ * Platform-specific index of the IRQ that will be used.
+ *
+ */
+#ifndef LKM_PLATFORM_IRQ_IDX
+#define LKM_PLATFORM_IRQ_IDX            0
+#endif
+
+
+/* end of file c_lkm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/lkm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/lkm.h
new file mode 100644
index 0000000..059664c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/lkm.h
@@ -0,0 +1,161 @@
+/* lkm.h
+ *
+ * Linux Kernel Module (LKM) interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef LKM_H_
+#define LKM_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // bool
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"                   // memcmp
+
+// Linux Kernel API
+#include <linux/types.h>            // resource_size_t
+#include <linux/compiler.h>         // __iomem
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    // Driver name
+    char * DriverName_p;
+
+    // Run-time power management data,
+    // pointer to struct dev_pm_ops containing device PM callbacks
+    void * PM_p;
+
+    // Implementation-specific initialization data, see implementation notes
+    void * CustomInitData_p;
+
+    // Identifier of the resource associated with the device controlled
+    // by the device driver implemented in the LKM
+    int ResId;
+
+    // Resource size in bytes
+    resource_size_t ResByteCount;
+
+    // Use Message Signaled Interrupts, true - use, false - do not use
+    bool fUseMSI;
+
+    // true - keep the device resource mapped after LKM initialization,
+    // false - unmap the device resource mapped after LKM initialization
+    bool fRetainMap;
+
+} LKM_Init_t;
+
+
+/*----------------------------------------------------------------------------
+ * LKM_Init
+ *
+ * Initializes the kernel module and registers it as a device driver
+ * in the kernel.
+ *
+ * Return value
+ *      >=0 - success
+ *      <0  - failure
+ */
+int
+LKM_Init(
+        LKM_Init_t * const InitData_p);
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_Uninit
+ *
+ * Uninitializes the kernel module registered with the LKM_Init() function.
+ *
+ * Return value
+ *      None
+ */
+void
+LKM_Uninit(void);
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_DeviceGeneric_Get
+ *
+ * Returns pointer to a generic Linux kernel struct device.
+ *
+ * Return value
+ *      Pointer to struct device.
+ */
+void *
+LKM_DeviceGeneric_Get(void);
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_DeviceSpecific_Get
+ *
+ * Returns pointer to a specific Linux kernel struct device,
+ * such as pci_dev for PCI, or platform_device for Platform.
+ *
+ * Return value
+ *      Pointer to struct device.
+ */
+void *
+LKM_DeviceSpecific_Get(void);
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_PhysBaseAddr_Get
+ *
+ * Returns a pointer to a physical base address of the device memory mapped
+ * IO space (physical resource address)
+ *
+ * Return value
+ *      Pointer to a physical resource address of the device.
+ */
+void *
+LKM_PhysBaseAddr_Get(void);
+
+
+/*-----------------------------------------------------------------------------
+ * LKM_MappedBaseAddr_Get
+ *
+ * Returns a pointer to a mapped to the kernel memory base address
+ * of the device memory mapped IO space (mapped or virtual resource address)
+ *
+ * Return value
+ *      Pointer to a mapped resource address of the device.
+ */
+void __iomem *
+LKM_MappedBaseAddr_Get(void);
+
+
+/* end of file lkm.h */
+
+
+#endif /* LKM_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/of/device_platform.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/of/device_platform.h
new file mode 100644
index 0000000..036f03c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/of/device_platform.h
@@ -0,0 +1,79 @@
+/* device_platform.h
+ *
+ * Driver Framework platform-specific interface,
+ * Linux user-space UMDevXS.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DEVICE_PLATFORM_H_
+#define DEVICE_PLATFORM_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t
+
+// Linux kernel API
+#include <linux/compiler.h>         // __iomem
+#include <linux/pci.h>              // pci_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Internal global device administration data
+typedef struct
+{
+    // Device data
+    struct platform_device * Platform_Device_p;
+
+    // Physical base address of the device resource (MMIO space)
+    void * PhysBaseAddr;
+
+    // Mapped (virtual) address of the device resource (MMIO space)
+    uint32_t __iomem * MappedBaseAddr_p;
+
+} Device_Platform_Global_t;
+
+// Internal device administration data
+typedef struct
+{
+    unsigned int Reserved; // not used
+
+} Device_Platform_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+#endif // DEVICE_PLATFORM_H_
+
+
+/* end of file device_platform.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/rpm_kernel_macros.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/rpm_kernel_macros.h
new file mode 100644
index 0000000..732c809
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/device/lkm/rpm_kernel_macros.h
@@ -0,0 +1,67 @@
+/* rpm_kernel_macros.h
+ *
+ * Runtime Power Management (RPM) Kernel Macros API
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2015-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_RPM_KERNEL_MACROS_H
+#define INCLUDE_GUARD_RPM_KERNEL_MACROS_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Forward declarations
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define RPM_SUCCESS     0   // No error
+
+#define RPM_OPS_INIT
+
+#define RPM_OPS_PM      NULL
+
+
+/*----------------------------------------------------------------------------
+ * RPM_INIT_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_INIT_MACRO(data)    RPM_SUCCESS
+
+
+/*----------------------------------------------------------------------------
+ * RPM_Uninit
+ *
+ * Expands into a single line expression
+ */
+#define RPM_UNINIT_MACRO()    RPM_SUCCESS
+
+
+#endif /* INCLUDE_GUARD_RPM_KERNEL_MACROS_H */
+
+
+/* rpm_kernel_macros.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_addr.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_addr.h
new file mode 100644
index 0000000..6fb9773
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_addr.h
@@ -0,0 +1,93 @@
+/* dmares_addr.h
+ *
+ * Driver Framework, DMAResource API, Address Translation functions
+ * Translates an {address + domain} to an address in a requested domain.
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_ADDR_H
+#define INCLUDE_GUARD_DMARES_ADDR_H
+
+#include "dmares_types.h"       // DMAResource_AddrDomain/AddrPair/Handle_t
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Translate
+ *
+ * Attempts to provide an address for a DMA Resource that can be used in the
+ * requested address domain. Typically used to get the address that can be
+ * used by a device to perform DMA.
+ *
+ * Handle (input)
+ *     The handle to the DMA Resource record that was returned by
+ *     DMAResource_Alloc, DMAResource_CheckAndRegister or DMAResource_Attach.
+ *
+ * DestDomain (input)
+ *     The requested domain to translate the address to.
+ *     Please check the implementation notes for supported domains.
+ *
+ * PairOut_p (output)
+ *     Pointer to the memory location when the converted address plus domain
+ *     will be written.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation dependent)
+ */
+int
+DMAResource_Translate(
+        const DMAResource_Handle_t Handle,
+        const DMAResource_AddrDomain_t DestDomain,
+        DMAResource_AddrPair_t * const PairOut_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_AddPair
+ *
+ * This function can be used to register another address pair known to the
+ * caller for a DMA Resource.
+ * The information will be stored in the DMA Resource Record and can be used
+ * by DMAResource_Translate.
+ * Typically used when an external DMA-safe buffer allocator returns two
+ * addresses (for example virtual and physical).
+ * Note: How many address pairs are supported is implementation specific.
+ *
+ * Handle (input)
+ *     The handle to the DMA Resource record that was returned by
+ *     DMAResource_CheckAndRegister or DMAResource_Attach.
+ *
+ * Pair (input)
+ *     Address pair (address + domain) to be associated with the DMA Resource.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation dependent)
+ */
+int
+DMAResource_AddPair(
+        const DMAResource_Handle_t Handle,
+        const DMAResource_AddrPair_t Pair);
+
+
+#endif /* Include Guard */
+
+/* end of file dmares_addr.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_buf.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_buf.h
new file mode 100644
index 0000000..0d3ad08
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_buf.h
@@ -0,0 +1,217 @@
+/* dmares_buf.h
+ *
+ * Driver Framework, DMAResource API, Buffer functions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_BUF_H
+#define INCLUDE_GUARD_DMARES_BUF_H
+
+#include "basic_defs.h"         // bool, uint8_t, uint32_t, inline
+#include "dmares_types.h"       // DMAResource_Handle/Properties_t
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Alloc
+ *
+ * Allocate a buffer of requested size that can be used for device DMA.
+ * DMAResource_Create is used to create a record and handle to administer
+ * the buffer.
+ *
+ * RequestedProperties
+ *     Requested properties of the buffer that will be allocated, including
+ *     the size, start address alignment, etc. See DMAResource_Properties_t.
+ *
+ * AddrPair_p (output)
+ *     Pointer to the memory location where the address and domain of the
+ *     buffer will be written by this function when allocation is successful.
+ *     This buffer address can then be used in the caller's memory domain.
+ *
+ * Handle_p (output)
+ *     Pointer to the memory location when the handle will be returned.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_Alloc(
+        const DMAResource_Properties_t RequestedProperties,
+        DMAResource_AddrPair_t * const AddrPair_p,
+        DMAResource_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_CheckAndRegister
+ *
+ * This function can be used to register an already allocated buffer that the
+ * caller wishes to use for DMA. The implementation checks whether the
+ * buffer is valid for DMA use. If this test passes, the buffer is registered
+ * and can be use as for DMAResource_Alloc and DMAResource_Attach.
+ * If the test fails, the buffer is rejected and not registered. The caller
+ * will then have to bounce the data to another DMA-safe buffer.
+ * The exact conditions for accepting or reject a buffer are implementation
+ * specific. Please check the implementation notes.
+ *
+ * The buffer must be accessible to the caller using the provided address. Use
+ * DMAResource_Attach for buffers that are not yet accessible to the caller.
+ * It is allowed to register a subset of a DMA resource.
+ * DMAResource_Create is used to create a record and handle to administrate
+ * the buffer.
+ *
+ * ActualProperties (input)
+ *     Properties that describe the buffer that is being registered.
+ *
+ * AddrPair (input)
+ *     Address and Domain of the buffer. The pointer in this structure must be
+ *     valid to use on the host in the domain of the caller.
+ *
+ * AllocatorRef (input)
+ *     Number to describe the source of this buffer. The exact numbers
+ *     supported is implementation specific. This provides some flexibility
+ *     for a specific implementation to provide address translation for a
+ *     number of allocators.
+ *
+ * Handle_p (output)
+ *     Pointer to the memory location when the handle will be returned when
+ *     registration is successful.
+ *
+ * Return Values
+ *     1    Rejected; buffer cannot be used for DMA
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_CheckAndRegister(
+        const DMAResource_Properties_t ActualProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        const char AllocatorRef,
+        DMAResource_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Attach
+ *
+ * This function must be used to make an already allocated buffer available
+ * in the memory domain of the caller (add it to the address map). Use this
+ * function instead of DMAResource_CheckAndRegister when an address of the
+ * buffer is available, but not for this memory domain.
+ * The exact memory domains supported by this function is implementation
+ * specific.
+ * DMAResource_Create is used to create a record and handle to administer
+ * the buffer.
+ *
+ * ActualProperties (input)
+ *     Properties that describe the buffer that is being registered.
+ *
+ * AddrPair (input)
+ *     Address and Domain of the buffer. The pointer in this structure is
+ *     NOT valid to use in the domain of the caller.
+ *
+ * Handle_p (output)
+ *     Pointer to the memory location when the handle will be returned.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_Attach(
+        const DMAResource_Properties_t ActualProperties,
+        const DMAResource_AddrPair_t AddrPair,
+        DMAResource_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Release
+ *
+ * This function must be used as a counter-operation for DMAResource_Alloc,
+ * DMAResource_CheckAndRegister and DMAResource_Attach. Allocated buffers are
+ * freed, attached buffers are detached and registered buffers are simply
+ * forgotten.
+ * The caller must ensure the buffers are not in use anymore when this
+ * function is called.
+ * The related record and handle are also destroyed using DMAResource_Destroy,
+ * so the handle and record cannot be used anymore when this function returns.
+ *
+ * Handle (input)
+ *     The handle to the DMA Resource record that was returned by
+ *     DMAResource_Alloc, DMAResource_CheckAndRegister or DMAResource_Attach.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_Release(
+        const DMAResource_Handle_t Handle);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_SwapEndianness_Set
+ *
+ * This function sets the endianness conversion option in the DMA resource
+ * record. This field is considered by the functions in dmares_rw.h that
+ * access integers.
+ *
+ * Handle (input)
+ *     The handle to the DMA Resource record that was returned by
+ *     DMAResource_Alloc, DMAResource_CheckAndRegister or DMAResource_Attach.
+ *
+ * fSwapEndianness
+ *     true  = swap byte order of the integer before writing or after reading.
+ *     false = do not swap byte order.
+ *
+ * Return Values
+ *     0    Success
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_SwapEndianness_Set(
+        const DMAResource_Handle_t Handle,
+        const bool fSwapEndianness);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_SwapEndianness_Get
+ *
+ * This function retrieves the endianness conversion option from the
+ * DMA resource record. See DMAResource_SwapEndianness_Set for details.
+ *
+ * Handle (input)
+ *     The handle to the DMA Resource record that was returned by
+ *     DMAResource_Alloc, DMAResource_CheckAndRegister or DMAResource_Attach.
+ *
+ * Return Values
+ *     0    Success; fSwapEndianness is false
+ *     1    Success; fSwapEndianness is true
+ *     <0   Error code (implementation specific)
+ */
+int
+DMAResource_SwapEndianness_Get(
+        const DMAResource_Handle_t Handle);
+
+
+#endif /* Include Guard */
+
+/* end of file dmares_buf.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_mgmt.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_mgmt.h
new file mode 100644
index 0000000..31a212f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_mgmt.h
@@ -0,0 +1,171 @@
+/* dmares_mgmt.h
+ *
+ * Driver Framework, DMAResource API, Management functions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_MGMT_H
+#define INCLUDE_GUARD_DMARES_MGMT_H
+
+#include "basic_defs.h"         // bool, uint32_t, inline
+#include "dmares_types.h"       // DMAResource_Handle/Record/AddrPair_t
+
+
+/*****************************************************************************
+ * DMA Resource API
+ *
+ * This API is related to management of memory buffers that can be accessed by
+ * the host as well as a device, using Direct Memory Access (DMA). A driver
+ * must typically support many of these shared resources. This API helps with
+ * administration of these resources.
+ *
+ * This API maintains administration records that the caller can read and
+ * write directly. A handle is also provided to abstract the record.
+ * The handle cannot be used to directly access the resource and is therefore
+ * considered safe to pass around in the system, even to applications.
+ *
+ * Another important aspect of this API is to provide a point where resources
+ * can be handed over between the host and the device. The driver library or
+ * adapter must call the PreDMA and PostDMA functions to indicate the hand over
+ * of access right between the host and the device for an entire resource, or
+ * part thereof. The implementation can use these calls to manage the
+ * data coherence for the resource, for example in a cached system.
+ *
+ * Dynamic DMA resources such as DMA-safe buffers covered by this API
+ * are different from static Device resources (see the Device API)
+ * which represent device-internal resources with possible read and write
+ * side-effects.
+ *
+ * On the fly endianness conversion (byte swap) for integers is supported for
+ * DMA resources by means of the Read32 and Write32 functions.
+ *
+ * Note: If multiple devices with a different memory view need to use the same
+ * DMA resource, then the caller should consider separate records for each
+ * device (for the same buffer).
+ */
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Init
+ *
+ * This function must be used to initialize the DMAResource administration.
+ * It must be called before any of the other DMAResource_* functions may be
+ * called. It may be called anew only after DMAResource_UnInit has been called.
+ *
+ * Return Value
+ *     true   Initialization successfully, rest of the API may now be used.
+ *     false  Initialization failed.
+ */
+bool
+DMAResource_Init(void);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_UnInit
+ *
+ * This function can be used to uninitialize the DMAResource administration.
+ * The caller must make sure that handles will not be used after this function
+ * returns.
+ * If memory was allocated by DMAResource_Init, this function will free it.
+ */
+void
+DMAResource_UnInit(void);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_CreateRecord
+ *
+ * This function can be used to create a record. The function returns a handle
+ * for the record. Use DMAResource_Handle2RecordPtr to access the record.
+ * Destroy the record when no longer required, see DMAResource_Destroy.
+ * This function initializes the record to all zeros.
+ *
+ * Return Values
+ *     Handle for the DMA Resource.
+ *     NULL is returned when the creation failed.
+ */
+DMAResource_Handle_t
+DMAResource_CreateRecord(void);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_DestroyRecord
+ *
+ * This function invalidates the handle and the record instance.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (DMAResource_Alloc /
+ *     DMAResource_CheckAndRegister / DMAResource_Attach).
+ *
+ * Return Values
+ *     None
+ */
+void
+DMAResource_DestroyRecord(
+        const DMAResource_Handle_t Handle);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_IsValidHandle
+ *
+ * This function tells whether a handle is valid.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (DMAResource_Alloc /
+ *     DMAResource_CheckAndRegister / DMAResource_Attach).
+ *
+ * Return Value
+ *     true   The handle is valid
+ *     false  The handle is NOT valid
+ */
+bool
+DMAResource_IsValidHandle(
+        const DMAResource_Handle_t Handle);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Handle2RecordPtr
+ *
+ * This function can be used to get a pointer to the DMA resource record
+ * (DMAResource_Record_t) for the provided handle. The pointer is valid until
+ * the record and handle are destroyed.
+ *
+ * Handle
+ *     A valid handle that was once returned by DMAResource_CreateRecord or
+ *     one of the DMA Buffer Management functions (DMAResource_Alloc /
+ *     DMAResource_CheckAndRegister / DMAResource_Attach).
+ *
+ * Return Value
+ *     Pointer to the DMAResource_Record_t memory for this handle.
+ *     NULL is returned if the handle is invalid.
+ */
+DMAResource_Record_t *
+DMAResource_Handle2RecordPtr(
+        const DMAResource_Handle_t Handle);
+
+
+#endif /* Include Guard */
+
+/* end of file dmares_mgmt.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_rw.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_rw.h
new file mode 100644
index 0000000..98ceaef
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_rw.h
@@ -0,0 +1,262 @@
+/* dmares_rw.h
+ *
+ * Driver Framework, DMAResource API, Read/Write and Pre/Post-DMA functions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_RW_H
+#define INCLUDE_GUARD_DMARES_RW_H
+
+#include "basic_defs.h"         // bool, uint32_t, inline
+#include "dmares_types.h"       // DMAResource_Handle_t
+
+
+/*****************************************************************************
+ * DMA Resource API
+ *
+ * This API is related to management of memory buffers that can be accessed by
+ * the host as well as a device, using Direct Memory Access (DMA). A driver
+ * must typically support many of these shared resources. This API helps with
+ * the administration of these resources.
+ *
+ * This API maintains administration records that the caller can read and
+ * write directly. A handle is also provided, to abstract the record.
+ * The handle cannot be used to directly access the resource and is therefore
+ * considered safe to pass around in the system, even to applications.
+ *
+ * Another important aspect of this API is to provide a point where resources
+ * can be handed over between the host and the device. The driver library or
+ * adapter must call the PreDMA and PostDMA functions to indicate the hand over
+ * of access right between the host and the device for an entire resource or
+ * part thereof. The implementation can use these calls to manage the
+ * data coherence for the resource, for example in a cached system.
+ *
+ * Dynamic DMA resources such as DMA-safe buffers covered by this API
+ * are different from static Device resources (see the Device API)
+ * which represent device-internal resources with possible read and write
+ * side-effects.
+ *
+ * Memory buffers are different from HWPAL_Device resources, which represent
+ * static device-internal resources with possible read and write side-effects.
+ *
+ * On the fly endianness swapping for words is supported for DMA Resources by
+ * means of the Read32 and Write32 functions.
+ *
+ * Note: If multiple devices with a different memory view need to use the same
+ * DMA resource then the caller should consider separate records for each
+ * device (for the same buffer).
+ */
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Read32
+ *
+ * This function can be used to read one 32bit word from the DMA Resource
+ * buffer.
+ * If required (decided by DMAResource_Record_t.device.fSwapEndianness),
+ * on the fly endianness conversion of the value read will be performed before
+ * it is returned to the caller.
+ *
+ * Handle (input)
+ *     Handle for the DMA Resource to access.
+ *
+ * WordOffset (input)
+ *     Offset in 32bit words, from the start of the DMA Resource to read from.
+ *
+ * Return Value
+ *     The value read.
+ *
+ * When the Handle and WordOffset parameters are not valid, the implementation
+ * will return an unspecified value.
+ */
+uint32_t
+DMAResource_Read32(
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Write32
+ *
+ * This function can be used to write one 32bit word to the DMA Resource.
+ * If required (decided by DMAResource_Record_t.device.fSwapEndianness),
+ * on the fly endianness conversion of the value to be written will be
+ * performed.
+ *
+ * Handle (input)
+ *     Handle for the DMA Resource to access.
+ *
+ * WordOffset (input)
+ *     Offset in 32bit words, from the start of the DMA Resource to write to.
+ *
+ * Value (input)
+ *     The 32bit value to write.
+ *
+ * Return Value
+ *     None
+ *
+ * The write can only be successful when the Handle and WordOffset
+ * parameters are valid.
+ */
+void
+DMAResource_Write32(
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const uint32_t Value);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Read32Array
+ *
+ * This function perform the same task as DMAResource_Read32 for an array of
+ * consecutive 32bit words.
+ *
+ * See DMAResource_Read32 for a more detailed description.
+ *
+ * Handle (input)
+ *     Handle for the DMA Resource to access.
+ *
+ * StartWordOffset (input)
+ *     Offset in 32bit words, from the start of the DMA Resource to start
+ *     reading from. The word offset in incremented for every word.
+ *
+ * WordCount (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Values_p (input)
+ *     Memory location to write the retrieved values to.
+ *     Note the ability to let Values_p point inside the DMAResource that is
+ *     being read from, allowing for in-place endianness conversion.
+ *
+ * Return Value
+ *     None.
+ *
+ * The read can only be successful when the Handle and StartWordOffset
+ * parameters are valid.
+ */
+void
+DMAResource_Read32Array(
+        const DMAResource_Handle_t Handle,
+        const unsigned int StartWordOffset,
+        const unsigned int WordCount,
+        uint32_t * Values_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Write32Array
+ *
+ * This function perform the same task as DMAResource_Write32 for an array of
+ * consecutive 32bit words.
+ *
+ * See DMAResource_Write32 for a more detailed description.
+ *
+ * Handle (input)
+ *     Handle for the DMA Resource to access.
+ *
+ * StartWordOffset (input)
+ *     Offset in 32bit words, from the start of the DMA Resource to start
+ *     writing from. The word offset in incremented for every word.
+ *
+ * WordCount (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Values_p (input)
+ *     Pointer to the memory where the values to be written are located.
+ *     Note the ability to let Values_p point inside the DMAResource that is
+ *     being written to, allowing for in-place endianness conversion.
+ *
+ * Return Value
+ *     None.
+ *
+ * The write can only be successful when the Handle and StartWordOffset
+ * parameters are valid.
+ */
+void
+DMAResource_Write32Array(
+        const DMAResource_Handle_t Handle,
+        const unsigned int StartWordOffset,
+        const unsigned int WordCount,
+        const uint32_t * Values_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_PreDMA
+ *
+ * This function must be called when the host has finished accessing the
+ * DMA resource and the device (using its DMA) is the next to access it.
+ * It is possible to hand off the entire DMA resource, or only a selected part
+ * of it by describing the part with a start offset and count.
+ *
+ * Handle (input)
+ *     Handle for the DMA Resource to (partially) hand off.
+ *
+ * ByteOffset (input)
+ *     Start offset within the DMA resource for the selected part to hand off
+ *     to the device.
+ *
+ * ByteCount (input)
+ *     Number of bytes from ByteOffset for the part of the DMA Resource to
+ *     hand off to the device.
+ *     Set to zero to hand off the entire DMA Resource.
+ *
+ * The driver framework implementation must use this call to ensure the data
+ * coherence of the DMA Resource.
+ */
+void
+DMAResource_PreDMA(
+        const DMAResource_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const unsigned int ByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_PostDMA
+ *
+ * This function must be called when the device has finished accessing the
+ * DMA resource and the host can reclaim ownership and access it.
+ * It is possible to reclaim ownership for the entire DMA resource, or only a
+ * selected part of it by describing the part with a start offset and count.
+ *
+ * Handle (input)
+ *     Handle for the DMA resource to (partially) hand off.
+ *
+ * ByteOffset (input)
+ *     Start offset within the DMA resource for the selected part to reclaim.
+ *
+ * ByteCount (input)
+ *     Number of bytes from ByteOffset for the part of the DMA Resource to
+ *     reclaim.
+ *     Set to zero to reclaim the entire DMA resource.
+ *
+ * The driver framework implementation must use this call to ensure the data
+ * coherence of the DMA resource.
+ */
+void
+DMAResource_PostDMA(
+        const DMAResource_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const unsigned int ByteCount);
+
+
+#endif /* Include Guard */
+
+/* end of file dmares_rw.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_types.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_types.h
new file mode 100644
index 0000000..46cf3cb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/dmares/dmares_types.h
@@ -0,0 +1,107 @@
+/* dmares_types.h
+ *
+ * Driver Framework, DMAResource API, Type Definitions
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_TYPES_H
+#define INCLUDE_GUARD_DMARES_TYPES_H
+
+#include "basic_defs.h"         // bool, uint8_t, uint32_t, inline
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Handle_t
+ *
+ * This handle represents a DMA Resource Record that holds information about
+ * a memory resource that can be accessed by a device using DMA, from another
+ * memory domain in the same host or from another host (CPU/DSP).
+ */
+
+typedef void * DMAResource_Handle_t;
+
+typedef unsigned int DMAResource_AddrDomain_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_AddrPair_t
+ *
+ * This type describes a dynamic resource address coupled with its memory
+ * domain. The caller is encouraged to store the address with the domain
+ * information.
+ * The use of 'void *' for the Address_p avoids unsafe void-pointer function
+ * output parameters in 99% of all cases. However, in some odd cases the
+ * Address_p part needs to be adapted and that is why Domain must be located
+ * first in the struct. It also guarantees that Address_p part starts always
+ * at the same offset.
+ */
+typedef struct
+{
+    DMAResource_AddrDomain_t Domain;    // Defines domain of Address_p
+    void * Address_p;                   // type ensures 64-bit support
+} DMAResource_AddrPair_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Properties_t
+ *
+ * Buffer properties. When allocating a buffer, these are the requested
+ * properties for the buffer. When registering or attaching to an externally
+ * allocated buffer these properties describe the already allocated buffer.
+ * The exact fields and values supported is implementation specific.
+ *
+ * For both uses, the data structure should be initialized to all zeros
+ * before filling in some or all of the fields. This ensures forward
+ * compatibility in case this structure is extended with more fields.
+ *
+ * Example usage:
+ *     DMAResource_Properties_t Props = {0};
+ *     Props.fIsCached = true;
+ */
+typedef struct
+{
+    uint32_t Size;       // size of the buffer in bytes
+    int Alignment;       // buffer start address alignment
+                         // examples: 4 for 32bit
+    uint8_t Bank;        // can be used to indicate on-chip memory
+    bool fCached;        // true = SW needs to control the coherency management
+} DMAResource_Properties_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMAResource_Record_t
+ *
+ * This type is the record that describes a DMAResource. The details of the
+ * type are implementation specific and therefore in a separate header file.
+ *
+ * Several DMAResource API functions return a handle to a newly instantiated
+ * record. Use DMAResource_Handle2RecordPtr to get a pointer to the actual
+ * record and to access fields in the record.
+ */
+
+#include "dmares_record.h"   // DMAResource_Record_t definition
+
+
+#endif /* Include Guard */
+
+/* end of file dmares_types.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cmd.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cmd.h
new file mode 100644
index 0000000..d6348a7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cmd.h
@@ -0,0 +1,96 @@
+/* firmware_eip207_api_cmd.h
+ *
+ * EIP-207 Firmware Packet Flow ID API:
+ *
+ * Defines codes for packet flows and special-case commands.
+ * These codes are included in command descriptors (input tokens) supplied
+ * to the Classification Engine.
+ *
+ * This API is defined by the EIP-207 Classification Firmware.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : firmware_eip197                                          */
+/*   Version       : 3.5                                                      */
+/*   Configuration : FIRMWARE-GENERIC                                         */
+/*                                                                            */
+/*   Date          : 2022-Dec-21                                              */
+/*                                                                            */
+/* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/* All rights reserved. Unauthorized use (including, without limitation,      */
+/* distribution and copying) is strictly prohibited. All use requires,        */
+/* and is subject to, explicit written authorization and nondisclosure        */
+/* agreements with Rambus, Inc. and/or its subsidiaries.                      */
+/*                                                                            */
+/* For more information or support, please go to our online support system at */
+/* https://sipsupport.rambus.com.                                             */
+/* In case you do not have an account for this system, please send an e-mail  */
+/* to sipsupport@rambus.com.                                                  */
+/* -------------------------------------------------------------------------- */
+
+#ifndef FIRMWARE_EIP207_API_CMD_H_
+#define FIRMWARE_EIP207_API_CMD_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Lookaside Crypto packet Flow
+#define FIRMWARE_EIP207_CMD_PKT_LAC       0x04
+
+// Lookaside IPsec packet flow
+#define FIRMWARE_EIP207_CMD_PKT_LIP       0x02
+
+// Inline IPsec packet flow
+#define FIRMWARE_EIP207_CMD_PKT_IIP       0x02
+
+// Lookaside IPsec packet flow, custom classification
+#define FIRMWARE_EIP207_CMD_PKT_LIP_CUST  0x03
+
+// Inline IPsec packet flow, custom classification
+#define FIRMWARE_EIP207_CMD_PKT_IIP_CUST  0x03
+
+// Lookaside IPsec with Token Builder offload packet flow
+#define FIRMWARE_EIP207_CMD_PKT_LAIP_TB   0x18
+
+// Lookaside Basic with Token Builder offload packet flow
+#define FIRMWARE_EIP207_CMD_PKT_LAB_TB    0x20
+
+// Inline Basic with Token Builder offload packet flow
+#define FIRMWARE_EIP207_CMD_PKT_IB_TB    0x20
+
+// Lookaside DTLS (including CAPWAP)
+#define FIRMWARE_EIP207_CMD_PKT_LDT       0x28
+
+// Inline DTLS (including CAPWAP)
+#define FIRMWARE_EIP207_CMD_PKT_IDT       0x28
+
+// Inline MACsec
+#define FIRMWARE_EIP207_CMD_PKT_IMA       0x38
+
+// Invalidate Transform Record command
+#define FIRMWARE_EIP207_CMD_INV_TR        0x06
+
+// Invalidate Flow Record command
+#define FIRMWARE_EIP207_CMD_INV_FR        0x05
+
+// Bit mask that enables the flow lookup. Otherwise the transform lookup is performed.
+#define FIRMWARE_EIP207_CMD_FLOW_LOOKUP   0x80
+
+#endif /* FIRMWARE_EIP207_API_CMD_H_ */
+
+
+/* end of file firmware_eip207_api_cmd.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cs.h
new file mode 100644
index 0000000..184c282
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_cs.h
@@ -0,0 +1,252 @@
+/* firmware_eip207_api_cs.h
+ *
+ * EIP-207 Firmware Classification API:
+ * Initialization functionality,
+ *
+ * This API is defined by the EIP-207 Classification Firmware
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : firmware_eip197                                          */
+/*   Version       : 3.5                                                      */
+/*   Configuration : FIRMWARE-GENERIC                                         */
+/*                                                                            */
+/*   Date          : 2022-Dec-21                                              */
+/*                                                                            */
+/* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/* All rights reserved. Unauthorized use (including, without limitation,      */
+/* distribution and copying) is strictly prohibited. All use requires,        */
+/* and is subject to, explicit written authorization and nondisclosure        */
+/* agreements with Rambus, Inc. and/or its subsidiaries.                      */
+/*                                                                            */
+/* For more information or support, please go to our online support system at */
+/* https://sipsupport.rambus.com.                                             */
+/* In case you do not have an account for this system, please send an e-mail  */
+/* to sipsupport@rambus.com.                                                  */
+/* -------------------------------------------------------------------------- */
+
+#ifndef FIRMWARE_EIP207_API_CS_H_
+#define FIRMWARE_EIP207_API_CS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"       // uint32_t, MASK_16_BITS
+
+// Firmware EIP-207 Classification API, Flow Control
+#include "firmware_eip207_api_flow_cs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// the recommended value for combining the write command in the cache client
+#define FIRMWARE_EIP207_RC_DMA_WR_COMB_DLY       0x07
+
+
+// Size of the Flow Record in 32-bit words
+#define FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT                \
+                                    FIRMWARE_EIP207_CS_FLOW_FRC_RECORD_WORD_COUNT
+
+// Size of the Small Transform Record in 32-bit words
+#define FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT                \
+                                    FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT
+
+// Size of the Large Transform Record in 32-bit words
+#define FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT_LARGE          \
+                                    FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE
+
+// Size of the Small ARC4 State Record in 32-bit words
+#define FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT                \
+                                    FIRMWARE_EIP207_CS_FLOW_ARC4RC_RECORD_WORD_COUNT
+
+// Size of the Large ARC4 State Record in 32-bit words
+#define FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT_LARGE          \
+                                    FIRMWARE_EIP207_CS_FLOW_ARC4RC_RECORD_WORD_COUNT_LARGE
+
+// Word offset of the Flow ID field in the flow record
+#define FIRMWARE_EIP207_CS_HASH_ID_WORD_OFFSET                  \
+                                    FIRMWARE_EIP207_CS_FLOW_FR_FLOW_ID_WORD_OFFSET
+
+// Flow ID field length in 32-bit words
+#define FIRMWARE_EIP207_CS_HASH_ID_FIELD_WORD_COUNT             \
+                                    FIRMWARE_EIP207_CS_FLOW_HASH_ID_FIELD_WORD_COUNT
+
+// Word offset of the Next Record Pointer field in the flow record
+#define FIRMWARE_EIP207_CS_NEXT_RECORD_WORD_OFFSET              \
+                                    FIRMWARE_EIP207_CS_FLOW_FR_NEXT_ADDR_WORD_OFFSET
+
+// Word offset of the Transform Record Pointer field in the flow record
+#define FIRMWARE_EIP207_CS_XFORM_RECORD_WORD_OFFSET             \
+                                    FIRMWARE_EIP207_CS_FLOW_FR_XFORM_OFFS_WORD_OFFSET
+
+// Word offset of the ARC4 State Record Pointer field in the flow record
+#define FIRMWARE_EIP207_CS_ARC4_RECORD_WORD_OFFSET              \
+                                    FIRMWARE_EIP207_CS_FLOW_FR_ARC4_ADDR_WORD_OFFSET
+
+// Classification Engine clocks per one tick for
+// the blocking next command logic
+typedef enum
+{
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_16 = 0,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_32,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_64,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_128,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_256,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_512,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_1024,
+    FIRMWARE_EIP207_CS_BLOCK_CLOCKS_2048,
+} FIRMWARE_EIP207_CS_BlockClocks_t;
+
+// Disable the "block next command" logic
+#define FIRMWARE_EIP207_CS_BLOCK_NEXT_COMMAND_LOGIC_DISABLE
+
+// A blocked Record Cache command will be released automatically after 3 ticks
+// of a free-running timer whose speed is set by this field.
+// Value 0 ticks every engine clock (for debugging), other values M
+// in the range 1...7 generate one tick every 2^(M+4) engine clocks.
+// Default value: 1 tick per 32 engine clocks, see also FIRMWARE_EIP207_CS_BlockClocks_t
+#ifndef FIRMWARE_EIP207_CS_BLOCK_NEXT_COMMAND_LOGIC_DISABLE
+#define FIRMWARE_EIP207_CS_FRC_BLOCK_TIMEBASE                   FIRMWARE_EIP207_CS_BLOCK_CLOCKS_32
+#define FIRMWARE_EIP207_CS_TRC_BLOCK_TIMEBASE                   FIRMWARE_EIP207_CS_BLOCK_CLOCKS_32
+#define FIRMWARE_EIP207_CS_ARC4RC_BLOCK_TIMEBASE                FIRMWARE_EIP207_CS_BLOCK_CLOCKS_32
+#endif // FIRMWARE_EIP207_CS_BLOCK_NEXT_COMMAND_LOGIC_DISABLE
+
+// Administration RAM byte offsets as opposed to PE_n_ICE_SCRATCH_RAM
+// 1 KB memory area base address in Classification Engine n
+#define FIRMWARE_EIP207_CS_WORD_OFFS                            4
+
+#define FIRMWARE_EIP207_CS_VERSION_BASE                          \
+                    ((0 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IPUE_VER_CAP_BYTE_OFFSET    \
+                    ((0 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IPUE_CAP_BYTE_OFFSET        \
+                    ((1 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IFPP_VER_CAP_BYTE_OFFSET    \
+                    ((2 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IFPP_CAP_BYTE_OFFSET        \
+                    ((3 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+// Administration RAM byte offsets as opposed to PE_n_OCE_SCRATCH_RAM
+// 1 KB memory area base address in Classification Engine n
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OPUE_VER_CAP_BYTE_OFFSET    \
+                    ((0 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OPUE_CAP_BYTE_OFFSET        \
+                    ((1 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OFPP_VER_CAP_BYTE_OFFSET    \
+                    ((2 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OFPP_CAP_BYTE_OFFSET        \
+                    ((3 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+// Trace windows in PE_n_ICE_SCRATCH_RAM
+#define FIRMWARE_EIP207_CS_TRACE_WINDOW_BASE                         \
+                    ((64 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IPUE_TRACE_WINDOW_BYTE_OFFSET   \
+                    ((64 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_IFPP_TRACE_WINDOW_BYTE_OFFSET   \
+                    ((80 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+// Trace windows in PE_n_OCE_SCRATCH_RAM
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OPUE_TRACE_WINDOW_BYTE_OFFSET   \
+                    ((64 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OFPP_TRACE_WINDOW_BYTE_OFFSET   \
+                    ((80 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+// Flow and Transform record size word byte offset
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_REC_SIZE_BYTE_OFFSET       \
+                    ((4 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+// Global statistics
+#define FIRMWARE_EIP207_CS_GLOBAL_STAT_BASE                     \
+                    ((12 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_LO_BYTE_OFFSET        \
+                    ((12 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_HI_BYTE_OFFSET        \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_LO_BYTE_OFFSET + (0x01 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_LO_BYTE_OFFSET   \
+                    ((14 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_HI_BYTE_OFFSET   \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_LO_BYTE_OFFSET + (0x01 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_LO_BYTE_OFFSET \
+                    ((16 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_HI_BYTE_OFFSET \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_LO_BYTE_OFFSET + (0x01 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_LO_BYTE_OFFSET \
+                    ((18 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_HI_BYTE_OFFSET \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_LO_BYTE_OFFSET + (0x01 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_PKT_BYTE_OFFSET    \
+                    ((20 * FIRMWARE_EIP207_CS_WORD_OFFS))
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_PKT_BYTE_OFFSET   \
+                    ((21 * FIRMWARE_EIP207_CS_WORD_OFFS))
+
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_PKT_BYTE_OFFSET + 4)
+
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_OUTPUT_LAST_BYTE_COUNT \
+                    (FIRMWARE_EIP207_CS_ADMIN_RAM_REC_SIZE_BYTE_OFFSET + 4)
+
+// token format
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_TOKEN_FORMAT_BYTE_OFFSET   (24 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+// DTLS record alignment (ICE admin RAM)
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_DTLS_HDR_SIZE_BYTE_OFFSET  (11 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+// Redir (OCE admin RAM)
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_REDIR_BYTE_OFFSET  (8 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+// ECN control (OCE admin RAM)
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_ECN_CONTROL_BYTE_OFFSET  (9 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+// PKTID (OCE admin RAM)
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_PKTID_BYTE_OFFSET  (7 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+// ARC4 offset control
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_ARC4_OFFSET_OFFSET         (25 * FIRMWARE_EIP207_CS_WORD_OFFS)
+
+/*----------------------------------------------------------------------------
+ * Firmware helper functions
+ */
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_CS_RecordSize_Read
+ *
+ * This function reads the EIP-207 firmware flow, transform and ARC4 state
+ * record size from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_CS_ADMIN_RAM_REC_SIZE_BYTE_OFFSET
+ *
+ * FlowRec_ByteCount_p (output)
+ *     Pointer to the memory where the flow record size in 32-bit words
+ *     will be stored
+ *
+ * XformRec_ByteCount_p (output)
+ *     Pointer to the memory where the transform record size in 32-bit words
+ *     will be stored
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_CS_RecordSize_Read(
+        const uint32_t Value,
+        unsigned int * const FlowRec_ByteCount_p,
+        unsigned int * const XformRec_ByteCount_p)
+{
+    *XformRec_ByteCount_p = (unsigned int)((Value >> 16) & MASK_16_BITS);
+    *FlowRec_ByteCount_p  = (unsigned int)((Value)       & MASK_16_BITS);
+}
+
+
+#endif /* FIRMWARE_EIP207_API_CS_H_ */
+
+
+/* end of file firmware_eip207_api_cs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_dwld.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_dwld.h
new file mode 100644
index 0000000..0190a0c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_dwld.h
@@ -0,0 +1,344 @@
+/* firmware_eip207_api_dwld.h
+ *
+ * EIP-207 Firmware Download API:
+ *
+ * This API is defined by the EIP-207 Classification Firmware
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : firmware_eip197                                          */
+/*   Version       : 3.5                                                      */
+/*   Configuration : FIRMWARE-GENERIC                                         */
+/*                                                                            */
+/*   Date          : 2022-Dec-21                                              */
+/*                                                                            */
+/* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/* All rights reserved. Unauthorized use (including, without limitation,      */
+/* distribution and copying) is strictly prohibited. All use requires,        */
+/* and is subject to, explicit written authorization and nondisclosure        */
+/* agreements with Rambus, Inc. and/or its subsidiaries.                      */
+/*                                                                            */
+/* For more information or support, please go to our online support system at */
+/* https://sipsupport.rambus.com.                                             */
+/* In case you do not have an account for this system, please send an e-mail  */
+/* to sipsupport@rambus.com.                                                  */
+/* -------------------------------------------------------------------------- */
+
+#ifndef FIRMWARE_EIP207_API_DWLD_H_
+#define FIRMWARE_EIP207_API_DWLD_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "basic_defs.h"         // uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// IPUE firmware program counter value where the engine must be started from
+// in order to perform the firmware version check in the debug mode
+#define FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR      0x07E0
+
+// IFPP firmware program counter value where the engine must be started from
+// in order to perform the firmware version check in the debug mode
+#define FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR      0x0FE0
+
+// OPUE firmware program counter value where the engine must be started from
+// in order to perform the firmware version check in the debug mode
+#define FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR      0x04E0
+
+// OFPP firmware program counter value where the engine must be started from
+// in order to perform the firmware version check in the debug mode
+#define FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR      0x04E0
+
+// Administration RAM byte offsets as opposed to PE_n_ICE_SCRATCH_RAM
+// 1 KB memory area base address in Classification Engine n
+#define FIRMWARE_EIP207_DWLD_WORD_OFFS                            4
+#define FIRMWARE_EIP207_DWLD_VERSION_BASE                         0
+
+// Input Pull-Up micro-Engine version word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_VERSION_BYTE_OFFSET    \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x00 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Input Flow Post-Processor micro-Engine version word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_VERSION_BYTE_OFFSET    \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x02 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Output Pull-Up micro-Engine version word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_VERSION_BYTE_OFFSET    \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x00 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Output Flow Post-Processor micro-Engine version word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_VERSION_BYTE_OFFSET    \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x02 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Input Pull-Up micro-Engine control word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_CTRL_BYTE_OFFSET       \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x05 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Input Flow Post-Processor micro-engine control word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_CTRL_BYTE_OFFSET       \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x06 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Output Pull-Up micro-Engine control word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_CTRL_BYTE_OFFSET       \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x05 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+// Output Flow Post-Processor micro-engine control word byte offset
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_CTRL_BYTE_OFFSET       \
+                    ((FIRMWARE_EIP207_DWLD_VERSION_BASE) + (0x06 * FIRMWARE_EIP207_DWLD_WORD_OFFS))
+
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT \
+                    (FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_CTRL_BYTE_OFFSET + 4)
+
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_OUTPUT_LAST_BYTE_COUNT \
+                    (FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_CTRL_BYTE_OFFSET + 4)
+
+typedef struct
+{
+    unsigned int Version_MaMiPa;
+    unsigned int Major;
+    unsigned int Minor;
+    unsigned int PatchLevel;
+    const uint32_t * Image_p;
+    unsigned int WordCount;
+
+} FIRMWARE_EIP207_DWLD_t;
+
+
+#define FIRMWARE_EIP207_IPUE_NAME "firmware_eip207_ipue.bin"
+#define FIRMWARE_EIP207_IFPP_NAME "firmware_eip207_ifpp.bin"
+#define FIRMWARE_EIP207_OPUE_NAME "firmware_eip207_opue.bin"
+#define FIRMWARE_EIP207_OFPP_NAME "firmware_eip207_ofpp.bin"
+#define FIRMWARE_EIP207_VERSION_MAJOR 3
+#define FIRMWARE_EIP207_VERSION_MINOR 5
+#define FIRMWARE_EIP207_VERSION_PATCH 0
+
+
+/*----------------------------------------------------------------------------
+ * Firmware helper functions
+ */
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_IPUE_GetReferences
+ *
+ * This function returns references to the IPUE firmware image
+ *
+ * FW_p (output)
+ *     Pointer to the memory location where the IPUE firmware parameters
+ *     as defined by the FIRMWARE_EIP207_DWLD_t data structure will be stored
+ *
+ * Return value
+ *     None
+ */
+void
+FIRMWARE_EIP207_DWLD_IPUE_GetReferences(
+        FIRMWARE_EIP207_DWLD_t * const FW_p);
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_IFPP_GetReferences
+ *
+ * This function returns references to the IFPP firmware image
+ *
+ * FW_p (output)
+ *     Pointer to the memory location where the IFPP firmware parameters
+ *     as defined by the FIRMWARE_EIP207_DWLD_t data structure will be stored
+ *
+ * Return value
+ *     None
+ */
+void
+FIRMWARE_EIP207_DWLD_IFPP_GetReferences(
+        FIRMWARE_EIP207_DWLD_t * const FW_p);
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_OPUE_GetReferences
+ *
+ * This function returns references to the OPUE firmware image
+ *
+ * FW_p (output)
+ *     Pointer to the memory location where the OPUE firmware parameters
+ *     as defined by the FIRMWARE_EIP207_DWLD_t data structure will be stored
+ *
+ * Return value
+ *     None
+ */
+void
+FIRMWARE_EIP207_DWLD_OPUE_GetReferences(
+        FIRMWARE_EIP207_DWLD_t * const FW_p);
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_OFPP_GetReferences
+ *
+ * This function returns references to the OFPP firmware image
+ *
+ * FW_p (output)
+ *     Pointer to the memory location where the IFPP firmware parameters
+ *     as defined by the FIRMWARE_EIP207_DWLD_t data structure will be stored
+ *
+ * Return value
+ *     None
+ */
+void
+FIRMWARE_EIP207_DWLD_OFPP_GetReferences(
+        FIRMWARE_EIP207_DWLD_t * const FW_p);
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_Version_Read
+ *
+ * This function reads the EIP-207 firmware major, minor and patch level
+ * numbers from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_VERSION_BYTE_OFFSET or
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_VERSION_BYTE_OFFSET
+ *
+ * Major_p (input)
+ *     Pointer to the memory where the firmware major number will be stored
+ *
+ * Minor_p (input)
+ *     Pointer to the memory where the firmware minor number will be stored
+ *
+ * PatchLevel_p (input)
+ *     Pointer to the memory where the firmware patch level number will
+ *     be stored
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_DWLD_Version_Read(
+        const uint32_t Value,
+        unsigned int * const Major_p,
+        unsigned int * const Minor_p,
+        unsigned int * const PatchLevel_p)
+{
+    *Major_p       = (unsigned int)((Value >> 8) & MASK_4_BITS);
+    *Minor_p       = (unsigned int)((Value >> 4) & MASK_4_BITS);
+    *PatchLevel_p  = (unsigned int)((Value)      & MASK_4_BITS);
+}
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_IPUE_VersionUpdated_Read
+ *
+ * This function reads the IPUE firmware version updated bit
+ * from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_CTRL_BYTE_OFFSET
+ *
+ * fVersionUpdated_p (output)
+ *     Pointer to the memory where the firmware version update flag
+ *     will be stored. The firmware updates this flag when started in
+ *     the debug mode at the Program Counter
+ *     FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_DWLD_IPUE_VersionUpdated_Read(
+        const uint32_t Value,
+        bool * const fVersionUpdated_p)
+{
+    *fVersionUpdated_p  = ((Value & BIT_0) != 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_IFPP_VersionUpdated_Read
+ *
+ * This function reads the IFPP firmware version updated bit
+ * from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_CTRL_BYTE_OFFSET
+ *
+ * fVersionUpdated_p (output)
+ *     Pointer to the memory where the firmware version update flag
+ *     will be stored. The firmware updates this flag when started in
+ *     the debug mode at the Program Counter
+ *     FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_DWLD_IFPP_VersionUpdated_Read(
+        const uint32_t Value,
+        bool * const fVersionUpdated_p)
+{
+    *fVersionUpdated_p  = ((Value & BIT_0) != 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_OPUE_VersionUpdated_Read
+ *
+ * This function reads the OPUE firmware version updated bit
+ * from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_CTRL_BYTE_OFFSET
+ *
+ * fVersionUpdated_p (output)
+ *     Pointer to the memory where the firmware version update flag
+ *     will be stored. The firmware updates this flag when started in
+ *     the debug mode at the Program Counter
+ *     FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_DWLD_OPUE_VersionUpdated_Read(
+        const uint32_t Value,
+        bool * const fVersionUpdated_p)
+{
+    *fVersionUpdated_p  = ((Value & BIT_0) != 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_DWLD_OFPP_VersionUpdated_Read
+ *
+ * This function reads the OFPP firmware version updated bit
+ * from the provided 32-bit value
+ *
+ * Value (input)
+ *     32-bit value that can be read from the Administration RAM byte offset
+ *     FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_CTRL_BYTE_OFFSET
+ *
+ * fVersionUpdated_p (output)
+ *     Pointer to the memory where the firmware version update flag
+ *     will be stored. The firmware updates this flag when started in
+ *     the debug mode at the Program Counter
+ *     FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_DWLD_OFPP_VersionUpdated_Read(
+        const uint32_t Value,
+        bool * const fVersionUpdated_p)
+{
+    *fVersionUpdated_p  = ((Value & BIT_0) != 0);
+}
+
+#endif /* FIRMWARE_EIP207_API_DWLD_H_ */
+/* end of file firmware_eip207_api_dwld.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_flow_cs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_flow_cs.h
new file mode 100644
index 0000000..c7b3f9d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/firmware_api/firmware_eip207_api_flow_cs.h
@@ -0,0 +1,484 @@
+/* firmware_eip207_api_flow_cs.h
+ *
+ * EIP-207 Firmware Classification API:
+ * Flow Control functionality,
+ *
+ * This API is defined by the EIP-207 Classification Firmware
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : firmware_eip197                                          */
+/*   Version       : 3.5                                                      */
+/*   Configuration : FIRMWARE-GENERIC                                         */
+/*                                                                            */
+/*   Date          : 2022-Dec-21                                              */
+/*                                                                            */
+/* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/* All rights reserved. Unauthorized use (including, without limitation,      */
+/* distribution and copying) is strictly prohibited. All use requires,        */
+/* and is subject to, explicit written authorization and nondisclosure        */
+/* agreements with Rambus, Inc. and/or its subsidiaries.                      */
+/*                                                                            */
+/* For more information or support, please go to our online support system at */
+/* https://sipsupport.rambus.com.                                             */
+/* In case you do not have an account for this system, please send an e-mail  */
+/* to sipsupport@rambus.com.                                                  */
+/* -------------------------------------------------------------------------- */
+
+#ifndef FIRMWARE_EIP207_API_FLOW_CS_H_
+#define FIRMWARE_EIP207_API_FLOW_CS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "basic_defs.h"     // uint32_t
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Size of the Flow Record in 32-bit words
+#define FIRMWARE_EIP207_CS_FLOW_FRC_RECORD_WORD_COUNT                       16
+
+// Size of the Transform Record in 32-bit words
+#define FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT                       64
+#define FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE                 80
+
+// Size of the ARC4 Record in 32-bit words
+#define FIRMWARE_EIP207_CS_FLOW_ARC4RC_RECORD_WORD_COUNT                    64
+#define FIRMWARE_EIP207_CS_FLOW_ARC4RC_RECORD_WORD_COUNT_LARGE              64
+
+// Word offset for ARC4 state record physical address
+#define FIRMWARE_EIP207_CS_FLOW_FR_ARC4_ADDR_WORD_OFFSET                    6
+
+// Flow ID field length in 32-bit words
+#define FIRMWARE_EIP207_CS_FLOW_HASH_ID_FIELD_WORD_COUNT                    4
+
+/*
+ * Flow Record field offsets
+ */
+
+ // Word offset for transform record physical address offset relative to cache base address
+#define FIRMWARE_EIP207_CS_FLOW_FR_XFORM_OFFS_WORD_OFFSET                   4
+
+// Word offset for transform record physical address
+#define FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_WORD_OFFSET                   5
+
+// Word offset for transform record physical address
+#define FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_HI_WORD_OFFSET                6
+
+// Word offset for software flow record host (virtual) address
+#define FIRMWARE_EIP207_CS_FLOW_FR_SW_ADDR_WORD_OFFSET                      8
+
+// Word offset for Flags field
+#define FIRMWARE_EIP207_CS_FLOW_FR_FLAGS_WORD_OFFSET                        9
+
+// Word offset for MTU/Interface ID field
+#define FIRMWARE_EIP207_CS_FLOW_FR_MTU_IFC_WORD_OFFSET                      3
+
+// Word offset for Next Hop MAC field (size of field is 3 words).
+#define FIRMWARE_EIP207_CS_FLOW_FR_NEXTHOP_MAC_WORD_OFFSET                  7
+
+// Word offset for NAT ports
+#define FIRMWARE_EIP207_CS_FLOW_FR_NAT_PORTS_WORD_OFFSET                    8
+
+// Word offset for NAT source address
+#define FIRMWARE_EIP207_CS_FLOW_FR_NAT_SRC_WORD_OFFSET                      9
+
+// Word offset for NAT destination address
+#define FIRMWARE_EIP207_CS_FLOW_FR_NAT_DST_WORD_OFFSET                      3
+
+// Word offset for time stamp 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_LO_WORD_OFFSET                12
+
+// Word offset for time stamp 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_HI_WORD_OFFSET                \
+                          (FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_LO_WORD_OFFSET + 1)
+
+// Word offset for octets statistics 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_LO_WORD_OFFSET                  14
+
+// Word offset for octets statistics 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_HI_WORD_OFFSET                  \
+                      (FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_LO_WORD_OFFSET + 1)
+
+// Word offset for packet statistics 32-bit value
+#define FIRMWARE_EIP207_CS_FLOW_FR_STAT_PKT_WORD_OFFSET                     10
+
+#define FIRMWARE_EIP207_CS_FLOW_FR_LAST_WORD_OFFSET                         \
+                       (FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_HI_WORD_OFFSET)
+
+#if (FIRMWARE_EIP207_CS_FLOW_FR_LAST_WORD_OFFSET + 1) != \
+                        FIRMWARE_EIP207_CS_FLOW_FRC_RECORD_WORD_COUNT
+#error "Error: Firmware EIP-207 flow record offsets do not match its size"
+#endif
+
+/*
+ * Transform Record field offsets
+ */
+// Maximum offset after storing all EIP96 context information, beyond which the
+// large record size and associated offsets must be used.
+#define FIRMWARE_EIP207_CS_FLOW_TR_LARGE_THRESHOLD_OFFSET                  56
+
+// Offset of extension data from start of transform record.
+#define FIRMWARE_EIP207_CS_FLOW_TR_EXTENSION_WORD_OFFSET                   56
+
+// Word offset for CCM salt value
+#define FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET                    56
+
+// Word offset for pad aligment.
+#define FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET                   50
+
+// Word offset for transform flags.
+#define FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET                       49
+
+// Word offset for Token Verify Instruction field, 32-bit word
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET                 54
+
+// Word offset for Token Context Instruction field, 32-bit word
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET                 55
+
+// Word offset for NAT-T ports
+#define FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET                  53
+
+// Word offset for time stamp 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET               58
+
+// Word offset for time stamp 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET                \
+                      (FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET + 1)
+
+// Word offset for octets statistics 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET                 62
+
+// Word offset for octets statistics 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET                  \
+                      (FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET + 1)
+
+// Word offset for packets statistics 32-bit value
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET                    60
+
+// Word offset for token header word.
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET                      48
+
+// Word offset for various byte-sized parameters.
+#define FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET                  52
+
+// Word offset for header proc context pointer.
+#define FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET                 51
+
+// Word offset for Tunnel IP source address
+#define FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET                  40
+
+// Word offset for Tunnel IP destination address
+#define FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET                  44 
+
+// Word offset for Tunnel IPv4 checksum
+#define FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET                    41
+
+// Word offset for Path MTU field
+#define FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET                    57
+
+#define FIRMWARE_EIP207_CS_FLOW_TR_LAST_WORD_OFFSET                        FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET
+
+#if (FIRMWARE_EIP207_CS_FLOW_TR_LAST_WORD_OFFSET + 1) > \
+                        FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT
+#error "Error: Firmware EIP-207 transform record offsets do not match its size"
+#endif
+
+/*
+ * Transform Record field offsets for large records
+ */
+
+// Offset of extension data from start of transform record.
+#define FIRMWARE_EIP207_CS_FLOW_TR_EXTENSION_WORD_OFFSET_LARGE          72
+
+// Word offset for CCM salt value
+#define FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET_LARGE           72
+
+// Word offset for pad aligment.
+#define FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET_LARGE          66
+
+// Word offset for transform flags.
+#define FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET_LARGE              65
+
+// Word offset for Token Verify Instruction field, 32-bit word
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET_LARGE        70
+
+// Word offset for Token Context Instruction field, 32-bit word
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET_LARGE       71
+
+// Word offset for NAT-T ports
+#define FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET_LARGE        69
+
+// Word offset for time stamp 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET_LARGE     74
+
+// Word offset for time stamp 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET_LARGE     \
+         (FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET_LARGE + 1)
+
+// Word offset for octets statistics 64-bit value, low 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET_LARGE       78
+
+// Word offset for octets statistics 64-bit value, high 32-bits
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET_LARGE       \
+         (FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET_LARGE + 1)
+
+// Word offset for packets statistics 32-bit value
+#define FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET_LARGE          76
+
+// Word offset for token header word.
+#define FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET_LARGE            64
+
+// Word offset for various byte-sized parameters.
+#define FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET_LARGE        68
+
+// Word offset for header proc context pointer.
+#define FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET_LARGE       67
+
+// Word offset for Tunnel IP source address
+#define FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET_LARGE        56
+
+// Word offset for Tunnel IP destination address
+#define FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET_LARGE        60
+
+// Word offset for Tunnel IPv4 checksum
+#define FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET_LARGE          \
+                      (FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET_LARGE + 1)
+
+// Word offset for Path MTU field
+#define FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET_LARGE          73
+
+#define FIRMWARE_EIP207_CS_FLOW_TR_LAST_WORD_OFFSET_LARGE                   \
+                       (FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET_LARGE)
+
+#if (FIRMWARE_EIP207_CS_FLOW_TR_LAST_WORD_OFFSET_LARGE + 1) > \
+                        FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE
+#error "Error: Firmware EIP-207 large transform record offsets do not match its size"
+#endif
+
+
+/*
+ * Flow hash ID calculation
+ */
+
+// The maximum size of the 32-bit word array that is used as data input for
+// the flow hash ID calculation
+#define FIRMWARE_EIP207_CS_FLOW_HASH_ID_INPUT_WORD_COUNT               13
+
+// Flags
+#define FIRMWARE_EIP207_CS_FLOW_SELECT_IPV4                            BIT_0
+#define FIRMWARE_EIP207_CS_FLOW_SELECT_IPV6                            BIT_1
+#define FIMRWARE_EIP207_CD_FLOW_SELECT_CUSTOM                          BIT_2
+#define FIMRWARE_EIP207_CD_FLOW_ESP_WITH_SRC                           BIT_3
+
+#define FIRMWARE_EIP207_CS_FLOW_DTLS_SUPPORTED                         1
+// This data structure represents the packet parameters (such as IP addresses
+// and ports) that select a particular flow.
+typedef struct
+{
+    // Flags, see FIRMWARE_EIP207_CS_FLOW_SELECT_*
+    uint32_t Flags;
+
+    // IP protocol number
+    uint8_t IpProto;
+
+    // IP source address
+    uint8_t * SrcIp_p;
+
+    // IP destination address
+    uint8_t * DstIp_p;
+
+    // Source port for UDP
+    uint16_t  SrcPort;
+
+    // Destination port for UDP
+    uint16_t  DstPort;
+
+    // Custom selection ID.
+    uint16_t  CustomID;
+
+    // SPI in IPsec
+    uint32_t  SPI;
+
+    // Epoch for inbound DTLS
+    uint16_t Epoch;
+
+} FIRMWARE_EIP207_CS_Flow_SelectorParams_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_CS_Flow_Selectors_Reorder
+ *
+ * This function re-orders the selectors for the flow hash ID calculation.
+ *
+ * Selectors_p (input)
+ *     Pointer to the data structure that contains the selectors from the
+ *     packet header that can be used for the flow hash ID calculation.
+ *
+ * OutData_p (output)
+ *     Pointer to the memory where the data arrays of 32-bit words
+ *     will be stored. The buffer for the array must be of size
+ *     FW207_CS_FLOW_HASH_ID_INPUT_WORD_COUNT.
+ *
+ * OutDataWordCount_p (output)
+ *     Pointer to the memory where the data arrays size in 32-bit words
+ *     will be stored.
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_CS_Flow_Selectors_Reorder(
+        const FIRMWARE_EIP207_CS_Flow_SelectorParams_t * const Selectors_p,
+        uint32_t * OutData_p,
+        unsigned int * const OutDataWordCount_p)
+{
+    unsigned int i = 0;
+
+    // Word 0
+    OutData_p[i++] = 0;
+
+    // Flags and IP protocol number
+    if ( Selectors_p->Flags & FIRMWARE_EIP207_CS_FLOW_SELECT_IPV6 )
+        OutData_p[i++] = (uint32_t)(Selectors_p->IpProto << 8) |
+                         (uint32_t)(BIT_25);
+    else
+        OutData_p[i++] = (uint32_t)(Selectors_p->IpProto << 8);
+
+    // SPI
+    OutData_p[i++] = Selectors_p->SPI;
+
+    // Epoch
+    OutData_p[i++] = Selectors_p->Epoch;
+
+    if (Selectors_p->Flags & FIMRWARE_EIP207_CD_FLOW_SELECT_CUSTOM)
+    {
+        // Custom ID (used instead of port numbers)
+        OutData_p[i++] = (uint32_t)Selectors_p->CustomID;
+    }
+    else if (Selectors_p->SPI == 0)
+    {
+        // L4 (TCP or UDP) destination and source port numbers
+        OutData_p[i++] = (uint32_t)Selectors_p->SrcPort |
+        (uint32_t)(Selectors_p->DstPort << 16);
+    }
+    else
+    {
+        OutData_p[i++] = 0;
+    }
+
+    // Destination IP address
+    OutData_p[i++] = (uint32_t)Selectors_p->DstIp_p[0]         |
+                     (uint32_t)(Selectors_p->DstIp_p[1] << 8)  |
+                     (uint32_t)(Selectors_p->DstIp_p[2] << 16) |
+                     (uint32_t)(Selectors_p->DstIp_p[3] << 24);
+
+    if ( Selectors_p->Flags & FIRMWARE_EIP207_CS_FLOW_SELECT_IPV6 )
+    {
+        OutData_p[i++] = (uint32_t)Selectors_p->DstIp_p[4]         |
+                         (uint32_t)(Selectors_p->DstIp_p[5] << 8)  |
+                         (uint32_t)(Selectors_p->DstIp_p[6] << 16) |
+                         (uint32_t)(Selectors_p->DstIp_p[7] << 24);
+        OutData_p[i++] = (uint32_t)Selectors_p->DstIp_p[8]         |
+                         (uint32_t)(Selectors_p->DstIp_p[9] << 8)  |
+                         (uint32_t)(Selectors_p->DstIp_p[10] << 16)|
+                         (uint32_t)(Selectors_p->DstIp_p[11] << 24);
+        OutData_p[i++] = (uint32_t)Selectors_p->DstIp_p[12]        |
+                         (uint32_t)(Selectors_p->DstIp_p[13] << 8) |
+                         (uint32_t)(Selectors_p->DstIp_p[14] << 16)|
+                         (uint32_t)(Selectors_p->DstIp_p[15] << 24);
+    }
+    else
+    {
+        OutData_p[i++] = 0;
+        OutData_p[i++] = 0;
+        OutData_p[i++] = 0;
+    }
+
+    // Source IP address
+    if (Selectors_p->SPI != 0 && (Selectors_p->Flags & FIMRWARE_EIP207_CD_FLOW_ESP_WITH_SRC) == 0)
+    {
+        OutData_p[i++] = 0;
+        OutData_p[i++] = 0;
+        OutData_p[i++] = 0;
+        OutData_p[i++] = 0;
+    }
+    else
+    {
+        OutData_p[i++] = (uint32_t)Selectors_p->SrcIp_p[0]         |
+                         (uint32_t)(Selectors_p->SrcIp_p[1] << 8)  |
+                         (uint32_t)(Selectors_p->SrcIp_p[2] << 16) |
+                         (uint32_t)(Selectors_p->SrcIp_p[3] << 24);
+        if ( Selectors_p->Flags & FIRMWARE_EIP207_CS_FLOW_SELECT_IPV6 )
+        {
+            OutData_p[i++] = (uint32_t)Selectors_p->SrcIp_p[4]         |
+                             (uint32_t)(Selectors_p->SrcIp_p[5] << 8)  |
+                             (uint32_t)(Selectors_p->SrcIp_p[6] << 16) |
+                             (uint32_t)(Selectors_p->SrcIp_p[7] << 24);
+            OutData_p[i++] = (uint32_t)Selectors_p->SrcIp_p[8]         |
+                             (uint32_t)(Selectors_p->SrcIp_p[9] << 8)  |
+                             (uint32_t)(Selectors_p->SrcIp_p[10] << 16)|
+                             (uint32_t)(Selectors_p->SrcIp_p[11] << 24);
+            OutData_p[i++] = (uint32_t)Selectors_p->SrcIp_p[12]        |
+                             (uint32_t)(Selectors_p->SrcIp_p[13] << 8) |
+                             (uint32_t)(Selectors_p->SrcIp_p[14] << 16)|
+                             (uint32_t)(Selectors_p->SrcIp_p[15] << 24);
+        }
+        else
+        {
+            OutData_p[i++] = 0;
+            OutData_p[i++] = 0;
+            OutData_p[i++] = 0;
+        }
+    }
+
+    *OutDataWordCount_p = i;
+}
+
+
+/*----------------------------------------------------------------------------
+ * FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read
+ *
+ * This function reads the word offset of the 32-bit Sequence Number field
+ * from the provided Token Context Instruction 32-bit word.
+ *
+ * Value (input)
+ *     Token Context Instruction 32-bit word.
+ *
+ * WordOffset_p (output)
+ *     Pointer to the memory where the word offset of the 32-bit Sequence Number
+ *     field will be stored.
+ *
+ * Return value
+ *     None
+ */
+static inline void
+FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read(
+        const uint32_t Value,
+        unsigned int * const WordOffset_p)
+{
+    *WordOffset_p = (unsigned int)(Value & MASK_8_BITS);
+}
+
+
+#endif /* FIRMWARE_EIP207_API_FLOW_CS_H_ */
+
+
+/* end of file firmware_eip207_api_flow_cs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/c_sa_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/c_sa_builder.h
new file mode 100644
index 0000000..8da114c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/c_sa_builder.h
@@ -0,0 +1,215 @@
+/* c_sa_builder.h
+ *
+ * Default configuration file for the SA Builder
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * Import the product specific configuration.
+ */
+#include "cs_sa_builder.h"
+
+
+/* Which protocol families are enabled? Enable the desired protocols.*/
+//#define SAB_ENABLE_PROTO_BASIC
+//#define SAB_ENABLE_PROTO_IPSEC
+//#define SAB_ENABLE_PROTO_SSLTLS
+//#define SAB_ENABLE_PROTO_MACSEC
+//#define SAB_ENABLE_PROTO_SRTP
+
+/* Which protocol-specific options are enabled? */
+//#define SAB_ENABLE_IPSEC_ESP
+//#define SAB_ENABLE_IPSEC_AH
+
+/* Algorithm selection, depending on what the hardware supports */
+
+/* Collectively enable all standard algorithms */
+//#define SAB_ENABLE_CRYPTO_STANDARD
+
+/* Enable SHA2-512 algorithms */
+//#define SAB_ENABLE_AUTH_SHA2_512
+
+/* Collectively enable all wireless algorithms */
+//#define SAB_ENABLE_CRYPTO_WIRELESS
+
+/* Collectively enable SM4, SM3 and related algorithms */
+//#define SAB_ENABLE_CRYPTO_SM4_SM3
+
+/* Enable AES-XTS */
+//#define SAB_ENABLE_CRYPTO_XTS
+
+/* Enable ARCFOUR */
+//#define SAB_ENABLE_CRYPTO_ARCFOUR
+
+/* Enable ChaCha20 and Poly1305 */
+//#define SAB_ENABLE_CRYPTO_CHACHAPOLY
+
+/* Enable SHA3 */
+//#define SAB_ENABLE_AUTH_SHA3
+
+/* Enable if the SA Builder must support extended use case for IPsec
+   processing */
+//#define SAB_ENABLE_IPSEC_EXTENDED
+
+/* Enable if the SA Builder must support extended use case for DTLS
+   processing */
+//#define SAB_ENABLE_DTLS_EXTENDED
+
+/* Enable if the SA Builder must support extended use case for MACsec
+   processing */
+//#define SAB_ENABLE_MACSEC_EXTENDED
+
+/* Enable if the SA Builder must support extended use case for Basic
+   processing */
+//#define SAB_ENABLE_BASIC_EXTENDED
+
+/* Enable if the SA Builder must support an engine with fixed SA records
+   (e.g. for a record cache) */
+//#define SAB_ENABLE_FIXED_RECORD_SIZE
+
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_DTLS_EXTENDED) || defined(SAB_ENABLE_MACSEC_EXTENDED) || defined(SAB_ENABLE_BASIC_EXTENDED)
+
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+#if !defined(SAB_ENABLE_PROTO_IPSEC) || !defined(SAB_ENABLE_IPSEC_ESP)
+#error "IPsec extended use case requires IPSEC and ESP protocols."
+#endif
+#endif
+
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+#ifndef SAB_ENABLE_PROTO_SSLTLS
+#error "DTLS extended use case requires SSL/TLS protocols."
+#endif
+#endif
+
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+#ifndef SAB_ENABLE_PROTO_MACSEC
+#error "MACSEC extended use case requires MACSEC protocols"
+#endif
+#endif
+
+// In the extended use case, always use a fixed record size, but do
+// not provide a value of that size here.
+#define SAB_ENABLE_FIXED_RECORD_SIZE
+
+// Set this if tunnel header fields are to be copied into the transform.
+// for extended use case.
+//#define SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+
+#else
+// Look-aside use case.
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifndef SAB_RECORD_WORD_COUNT
+// Specify the number of words of an SA record when the record size is fixed.
+#define SAB_RECORD_WORD_COUNT 64
+#endif
+#endif
+#endif
+
+// Set this if there are two fixed record sizes:
+// SAB_RECORD_WORD_COUNT and SAB_RECORD_WORD_COUNT_LARGE,
+// select the large one if the context size exceeds
+// SAB_LARGE_RECORD_TRHESHOLD_WORD_COUNT.
+//#define SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+
+#ifndef SAB_LARGE_TRANSFORM_OFFSET
+#define SAB_LARGE_TRANSFORM_OFFSET 16
+#endif
+
+/* Enable specific crypto and authentication algorithms. The following
+   are standard algorithms, normally always selected.*/
+//#define SAB_ENABLE_CRYPTO_AES
+//#define SAB_ENABLE_CRYPTO_GCM
+//#define SAB_ENABLE_CRYPTO_3DES
+//#define SAB_ENABLE_AUTH_MD5
+//#define SAB_ENABLE_AUTH_SHA1
+//#define SAB_ENABLE_AUTH_SHA2_256
+#ifdef SAB_ENABLE_CRYPTO_STANDARD
+#define SAB_ENABLE_CRYPTO_AES
+#define SAB_ENABLE_CRYPTO_GCM
+#define SAB_ENABLE_CRYPTO_3DES
+#define SAB_ENABLE_AUTH_MD5
+#define SAB_ENABLE_AUTH_SHA1
+#define SAB_ENABLE_AUTH_SHA2_256
+#endif
+
+/* Wireless algorihms */
+//#define SAB_ENABLE_CRYPTO_KASUMI
+//#define SAB_ENABLE_CRYPTO_SNOW
+//#define SAB_ENABLE_CRYPTO_ZUC
+#ifdef SAB_ENABLE_CRYPTO_WIRELESS
+#define SAB_ENABLE_CRYPTO_KASUMI
+#define SAB_ENABLE_CRYPTO_SNOW
+#define SAB_ENABLE_CRYPTO_ZUC
+#endif
+
+/* SM4-SM3 algorithms */
+//#define SAB_ENABLE_CRYPTO_SM4
+//#define SAB_ENABLE_CRYPTO_BC0
+//#define SAB_ENABLE_AUTH_SM3
+#ifdef SAB_ENABLE_CRYPTO_SM4_SM3
+#define SAB_ENABLE_CRYPTO_SM4
+#define SAB_ENABLE_CRYPTO_BC0
+#define SAB_ENABLE_AUTH_SM3
+#endif
+
+/* Enable this if the hardware supports 384-bitsequence number
+   masks. If SAB_ENABLE_256BIT_SEQMASK not also set, support 256-bit
+   masks via a work-around.*/
+//#define SAB_ENABLE_384BIT_SEQMASK
+
+/* Enable this if the hardware supports 256-bit sequence
+   number masks. */
+//#define SAB_ENABLE_256BIT_SEQMASK
+
+/* Enable this to use fixed offsets for sequence number masks regardless of
+   size. This only works on hardware that supports 384-bit masks. */
+//#define SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+
+/* Enable this to support building an SA for LTE firmware*/
+//#define SAB_ENABLE_LTE_FIRMWARE
+
+/* Enable this if you desire to include the ARC4 state in the SA
+   record. This requires the hardware to be configured for relative
+   ARC4 state offsets */
+//#define SAB_ARC4_STATE_IN_SA
+
+
+/* When the ARC4 state is included in the SA record, specify the
+   alignment requirements for this state.
+ */
+#ifndef SAB_ARC4_STATE_ALIGN_BYTE_COUNT
+#define SAB_ARC4_STATE_ALIGN_BYTE_COUNT 4
+#endif
+
+
+/* Strict checking of function arguments if enabled */
+//#define SAB_STRICT_ARGS_CHECK
+
+/* Call Token Context Generation in SA Builder */
+//#define SAB_AUTO_TOKEN_CONTEXT_GENERATION
+
+/* log level for the SA builder.
+   choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT */
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_CRIT
+#endif
+
+
+/* end of file c_sa_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder.h
new file mode 100644
index 0000000..512f375
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder.h
@@ -0,0 +1,157 @@
+/* sa_builder.h
+ *
+ * Main API for the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_H_
+#define SA_BUILDER_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+typedef enum
+{
+    SAB_STATUS_OK,
+    SAB_INVALID_PARAMETER,
+    SAB_UNSUPPORTED_FEATURE,
+    SAB_ERROR
+} SABuilder_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_GetSizes();
+ *
+ * Compute the required sizes in 32-bit words of any of up to three memory
+ * areas used by the SA.
+ *
+ * SAParams_p (input)
+ *   Pointer to the SA parameters structure.
+ * SAWord32Count_p (output)
+ *   The size of the normal SA buffer,
+ * SAStateWord32Count_p (output)
+ *   The size of any SA state record.
+ * ARC4StateWord32Count_p (output) T
+ *   The size of any ARCFOUR state buffer (output).
+ *
+ * When the SA state record or ARCFOUR state buffer are not required by
+ * the packet engine for this transform, the corresponding size outputs
+ * are returned as zero.
+ *
+ * If any of the output parameters is a null pointer,
+ * the corresponding size will not be returned.
+ *
+ * The SAParams_p structure must be fully filled in: it must have the
+ * same contents as it would have when SABuilder_BuildSA is called.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when the record referenced by SAParams_p is invalid,
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_GetSizes(
+    SABuilder_Params_t *const SAParams_p,
+    unsigned int *const SAWord32Count_p,
+    unsigned int *const SAStateWord32Count_p,
+    unsigned int *const ARC4StateWord32Count_p);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_BuildSA();
+ *
+ * Construct the SA record for the operation described in SAParams_p in
+ * up to three memory buffers. Update the field offset values in the
+ * SA parameter structure.
+ *
+ * SAParams_p (input, output)
+ *    Pointer to the SA parameters structure. Field offset values will
+ *    be updated.
+ * SABuffer_p (output)
+ *    Pointer to the the normal SA buffer,
+ * SAStateBuffer_p (output)
+ *    Pointer to the SA state record buffer,
+ * ARC4StateBuffer_p (output)
+ *    Pointer to the ARCFOUR state buffer.
+ *
+ * Each of the Buffer arguments must point to a word-aligned
+ * memory buffer whose size in words is at least equal to the
+ * corresponding size parameter returned by SABuilder_GetSizes().
+ *
+ * If any of the three buffers is not required for the SA (the
+ * corresponding size in SABuilder_GetSizes() is 0), the corresponding
+ * Buffer arguments to this function may be a null pointer.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_BuildSA(
+    SABuilder_Params_t * const SAParams_p,
+    uint32_t *const SABuffer_p,
+    uint32_t *const SAStateBuffer_p,
+    uint32_t *const ARC4StateBuffer_p);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetLargeTransformOffset();
+ *
+ * Set the (global) offset between the fields in Large transform records versus
+ * small transform records. For some hardware configurations (especially those
+ * with 1024-bit anti-replay masks) large transform records must contain more
+ * space than usual. This function is intended to be used when the hardware
+ * configuration is only known at runtime.
+ *
+ * Offset (inout)
+ *     Offset value in words.
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when the offset is out of range.
+ * SAB_UNSUPPORTED_FEATURE when the SA Builder is configured without support
+ * for this feature.
+ */
+SABuilder_Status_t
+SABuilder_SetLargeTransformOffset(
+    unsigned int Offset);
+
+
+#endif /* SA_BUILDER_H_ */
+
+
+/* end of file sa_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_basic.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_basic.h
new file mode 100644
index 0000000..9c75407
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_basic.h
@@ -0,0 +1,82 @@
+/* sa_builder_basic.h
+ *
+ * Basic Crypto/hash specific functions of the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef  SA_BUILDER_BASIC_H_
+#define SA_BUILDER_BASIC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+#include "sa_builder.h"
+#include "sa_builder_params_basic.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_Basic
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_Basic_t extension with sensible defaults for
+ * basic crypto and hash processing..
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsBasic_p (output)
+ *   Pointer to Basic parameter extension to be filled in
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. Either the cipher algorithm or the authentication algorithm
+ * or both can be set to one of the supported algorithms for
+ * basic crypto or basic hash or HMAC. If they are both left at NULL. the
+ * SA will be a bypass SA. The crypto mode and IV source
+ * can be specified as well.  Any required keys have to be specified
+ * as well.
+ *
+ * Both the SAParams_p and SAParamsBasic_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsBasic_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_Basic(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_Basic_t * const SAParamsBasic_p,
+    const SABuilder_Direction_t direction);
+
+
+#endif /* SA_BUILDER_BASIC_H_ */
+
+
+/* end of file sa_builder_basic.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_extended_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_extended_internal.h
new file mode 100644
index 0000000..8bb6328
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_extended_internal.h
@@ -0,0 +1,322 @@
+/* sa_builder_extended_internal.h
+ *
+ * Internal API of the EIP-96 SA Builder.
+ * - layout of the control words.
+ * - Data structure that represents the SA builder state.
+ * - Headers for shared functions and protocol-specific functions.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_EXTENDED_INTERNAL_H_
+#define SA_BUILDER_EXTENDED_INTERNAL_H_
+
+#include "c_sa_builder.h"
+#include "sa_builder_internal.h"
+#include "firmware_eip207_api_flow_cs.h"
+
+
+// In the extended use case, take the record word count from the firmware
+// package instead of any local definition.
+#undef SAB_RECORD_WORD_COUNT
+#define SAB_RECORD_WORD_COUNT FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+#define SAB_RECORD_WORD_COUNT_LARGE FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE
+#define SAB_LARGE_RECORD_THRESHOLD_WORD_COUNT FIRMWARE_EIP207_CS_FLOW_TR_LARGE_THRESHOLD_OFFSET
+#endif
+
+#define SAB_PACKBYTES(b0,b1,b2,b3) (((b3)<<24)|((b2)<<16)|((b1)<<8)|(b0))
+
+
+/* The protocol values have to agree with those used by the EIP-207 firmware.
+ */
+typedef enum
+{
+    SAB_ESP_PROTO_NONE = 0,
+    SAB_ESP_PROTO_OUT_CBC = 1,
+    SAB_ESP_PROTO_OUT_NULLAUTH = 2,
+    SAB_ESP_PROTO_OUT_CTR = 3,
+    SAB_ESP_PROTO_OUT_CCM = 4,
+    SAB_ESP_PROTO_OUT_GCM = 5,
+    SAB_ESP_PROTO_OUT_GMAC = 6,
+    SAB_ESP_PROTO_IN_CBC = 7,
+    SAB_ESP_PROTO_IN_NULLAUTH = 8,
+    SAB_ESP_PROTO_IN_CTR = 9,
+    SAB_ESP_PROTO_IN_CCM = 10,
+    SAB_ESP_PROTO_IN_GCM = 11,
+    SAB_ESP_PROTO_IN_GMAC = 12,
+    SAB_DTLS_PROTO_OUT_CBC = 13,
+    SAB_DTLS_PROTO_OUT_GCM = 14,
+    SAB_DTLS_PROTO_IN_CBC = 15,
+    SAB_DTLS_PROTO_IN_GCM = 16,
+    SAB_MACSEC_PROTO_OUT_GCM = 17,
+    SAB_MACSEC_PROTO_OUT_GMAC = 18,
+    SAB_MACSEC_PROTO_IN_GCM = 19,
+    SAB_MACSEC_PROTO_IN_GMAC = 20,
+    SAB_BASIC_PROTO_OUT_ENCHASH = 21,
+    SAB_BASIC_PROTO_IN_HASHDEC = 22,
+    SAB_BASIC_PROTO_OUT_HASHENC = 23,
+    SAB_BASIC_PROTO_IN_DECHASH = 24,
+    SAB_ESP_PROTO_OUT_CHACHAPOLY = 25,
+    SAB_ESP_PROTO_IN_CHACHAPOLY = 26,
+    SAB_DTLS_PROTO_OUT_CHACHAPOLY = 27,
+    SAB_DTLS_PROTO_IN_CHACHAPOLY = 28,
+    SAB_ESP_PROTO_OUT_XFRM_CBC = 31,
+    SAB_ESP_PROTO_IN_XFRM_CBC = 32,
+    SAB_ESP_PROTO_OUT_XFRM_GCM = 33,
+    SAB_ESP_PROTO_IN_XFRM_GCM = 34,
+} SABuilder_ESPProtocol_t;
+
+typedef enum
+{
+    SAB_HDR_BYPASS = 0,
+    SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS = 1,
+    SAB_HDR_IPV4_OUT_TUNNEL = 2,
+    SAB_HDR_IPV4_IN_TRANSP_HDRBYPASS = 3,
+    SAB_HDR_IPV4_IN_TUNNEL = 4,
+    SAB_HDR_IPV4_OUT_TRANSP = 5,
+    SAB_HDR_IPV4_IN_TRANSP = 6,
+    SAB_HDR_IPV6_OUT_TUNNEL = 7,
+    SAB_HDR_IPV6_IN_TUNNEL = 8,
+    SAB_HDR_IPV6_OUT_TRANSP_HDRBYPASS = 9,
+    SAB_HDR_IPV6_IN_TRANSP_HDRBYPASS = 10,
+    SAB_HDR_IPV6_OUT_TRANSP = 11,
+    SAB_HDR_IPV6_IN_TRANSP = 12,
+
+    /* DTLS and DLTS-CAPWAP */
+    SAB_HDR_IPV4_OUT_DTLS = 13,
+    SAB_HDR_IPV4_IN_DTLS = 14,
+    SAB_HDR_IPV6_OUT_DTLS = 15,
+    SAB_HDR_IPV6_IN_DTLS = 16,
+    SAB_HDR_IPV4_OUT_DTLS_CAPWAP = 17,
+    SAB_HDR_IPV4_IN_DTLS_CAPWAP = 18,
+    SAB_HDR_IPV6_OUT_DTLS_CAPWAP = 19,
+    SAB_HDR_IPV6_IN_DTLS_CAPWAP = 20,
+
+    /* IPsec with NAT-T. Must be in the same order as the non NAT-T
+       counterparts */
+    SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT = 21,
+    SAB_HDR_IPV4_OUT_TUNNEL_NATT = 22,
+    SAB_HDR_IPV4_IN_TRANSP_HDRBYPASS_NATT = 23,
+    SAB_HDR_IPV4_IN_TUNNEL_NATT = 24,
+    SAB_HDR_IPV4_OUT_TRANSP_NATT = 25,
+    SAB_HDR_IPV4_IN_TRANSP_NATT = 26,
+    SAB_HDR_IPV6_OUT_TUNNEL_NATT = 27,
+    SAB_HDR_IPV6_IN_TUNNEL_NATT = 28,
+    SAB_HDR_IPV6_OUT_TRANSP_HDRBYPASS_NATT = 29,
+    SAB_HDR_IPV6_IN_TRANSP_HDRBYPASS_NATT = 30,
+    SAB_HDR_IPV6_OUT_TRANSP_NATT = 31,
+    SAB_HDR_IPV6_IN_TRANSP_NATT = 32,
+
+    /* MACsec */
+    SAB_HDR_MACSEC_OUT = 33,
+    SAB_HDR_MACSEC_IN = 34,
+
+    /* BASIC */
+    SAB_HDR_BASIC_OUT_ZPAD  = 35,
+    SAB_HDR_BASIC_IN_NO_PAD = 36,
+    SAB_HDR_BASIC_OUT_TPAD  = 37,
+    SAB_HDR_BASIC_IN_PAD    = 38,
+
+    /* ESP with XFRM API */
+    SAB_HDR_IPV4_OUT_XFRM   = 39,
+    SAB_HDR_IPV6_OUT_XFRM   = 40,
+    SAB_HDR_IPV4_IN_XFRM   = 41,
+    SAB_HDR_IPV6_IN_XFRM   = 42,
+
+} SABuilder_HeaderProtocol_t;
+
+
+/* Values to construct the Token Header Word */
+#define SAB_HEADER_RC_NO_REUSE       0x00000000
+#define SAB_HEADER_RC_REUSE          0x00100000
+#define SAB_HEADER_RC_AUTO_REUSE     0x00200000
+
+#define SAB_HEADER_IP                0x00020000
+
+#define SAB_HEADER_DEFAULT           (SAB_HEADER_RC_NO_REUSE | SAB_HEADER_IP)
+
+#define SAB_HEADER_C                 0x02000000
+
+#define SAB_HEADER_UPD_HDR           0x00400000
+#define SAB_HEADER_APP_RES           0x00800000
+#define SAB_HEADER_PAD_VERIFY        0x01000000
+
+#define SAB_HEADER_IV_DEFAULT        0x00000000
+#define SAB_HEADER_IV_PRNG           0x04000000
+
+
+/* Used to construct the CCM Salt */
+#define SAB_CCM_FLAG_ADATA_L4        0x43
+
+
+/* Used to construct the VERIFY instruction */
+#define SAB_VERIFY_NONE     0xd0060000 /* No options set, use for outbound */
+#define SAB_VERIFY_PAD      0xd1060000 /* Verify padding only */
+#define SAB_VERIFY_PADSPI   0xd5060000 /* Verify padding and SPI */
+#define SAB_VERIFY_BIT_H    0x00010000 /* Add this bit to verify hash */
+#define SAB_VERIFY_BIT_SEQ  0x08000000 /* Add this bit to verify sequence number*/
+
+/* Used to construct the CTX instruction */
+/* Inbound */
+#define SAB_CTX_SEQNUM      0xe0561800 /* Update context from sequence number */
+#define SAB_CTX_INSEQNUM    0xe02e1800 /* Update context from sequence
+                                          number, skip seqnumhi, then
+                                          mask, so use on inbound without
+                                          exteded sequence number */
+/* Outbound */
+#define SAB_CTX_OUT_SEQNUM      0xe0560800 /* Update context from sequence number */
+#define SAB_CTX_OUT_INSEQNUM    0xe02e0800 /* Update context from sequence
+                                              number, skip seqnumhi, then
+                                              mask, so use on inbound without
+                                              exteded sequence number */
+
+#define SAB_CTX_NONE        0xe1560000 /* Use on confidentiality-only
+                                          protocols, combined with unused
+                                          offset in record */
+
+
+/* Used to construct RETR/INS instructions for IV */
+#define SA_RETR_HASH_IV0 0x42a00000
+#define SA_INS_NONE_IV0  0x20a00000
+#define SA_RETR_HASH_IV1 0x42a80000
+#define SA_INS_NONE_IV1  0x20a80000
+
+
+/* This variable contains the difference between the offsets of firmware fields
+   in large transform records compared to small transform records.
+   This is normally 16, but it can be larger when anti-replay masks of
+   1024 or more are supported.*/
+extern unsigned int LargeTransformOffset;
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedIPsecParams(SABuilder_Params_t *const SAParams_p,
+                               SABuilder_State_t * const SAState_p,
+                               uint32_t * const SABuffer_p);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedDTLSParams
+ *
+ * Fill in DTLS-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedDTLSParams(SABuilder_Params_t *const SAParams_p,
+                                SABuilder_State_t * const SAState_p,
+                                uint32_t * const SABuffer_p);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedMACsecParams(SABuilder_Params_t *const SAParams_p,
+                                SABuilder_State_t * const SAState_p,
+                                uint32_t * const SABuffer_p);
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedBasicParams
+ *
+ * Fill in Basic-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedBasicParams(SABuilder_Params_t *const SAParams_p,
+                                 SABuilder_State_t * const SAState_p,
+                                 uint32_t * const SABuffer_p);
+
+
+#endif /* SA_BUILDER_EXTENDED_INTERNAL_H_ */
+
+
+/* end of file sa_builder_extended_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_internal.h
new file mode 100644
index 0000000..abc233d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_internal.h
@@ -0,0 +1,453 @@
+/* sa_builder_internal.h
+ *
+ * Internal API of the EIP-96 SA Builder.
+ * - layout of the control words.
+ * - Data structure that represents the SA builder state.
+ * - Headers for shared functions and protocol-specific functions.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_INTERNAL_H_
+#define SA_BUILDER_INTERNAL_H_
+#include "c_sa_builder.h"
+#include "sa_builder.h"
+
+
+/* Type of packet field in Control Word 0 */
+
+#define SAB_CW0_TOP_NULL_OUT        0x00000000
+#define SAB_CW0_TOP_NULL_IN         0x00000001
+#define SAB_CW0_TOP_HASH_OUT        0x00000002
+#define SAB_CW0_TOP_HASH_IN         0x00000003
+#define SAB_CW0_TOP_ENCRYPT         0x00000004
+#define SAB_CW0_TOP_DECRYPT         0x00000005
+#define SAB_CW0_TOP_ENCRYPT_HASH    0x00000006
+#define SAB_CW0_TOP_DECRYPT_HASH    0x00000007
+#define SAB_CW0_TOP_HASH_ENCRYPT    0x0000000e
+#define SAB_CW0_TOP_HASH_DECRYPT    0x0000000f
+
+/* Flags to indicate SA properties to other software components.
+   They will be stored inside the per-packet options field in the SA and
+   as such they will never be user by hardware. */
+#define SAB_CW0_SW_IS_LARGE         0x00000010
+
+/* Cryptographic algorith, field (and key bit) */
+
+#define SAB_CW0_CRYPTO_NULL         0x00000000
+#define SAB_CW0_CRYPTO_DES          0x00010000
+#define SAB_CW0_CRYPTO_ARC4         0x00030000
+#define SAB_CW0_CRYPTO_3DES         0x00050000
+#define SAB_CW0_CRYPTO_KASUMI       0x00070000
+#define SAB_CW0_CRYPTO_AES_128      0x000b0000
+#define SAB_CW0_CRYPTO_AES_192      0x000d0000
+#define SAB_CW0_CRYPTO_AES_256      0x000f0000
+#define SAB_CW0_CRYPTO_SNOW         0x00130000
+#define SAB_CW0_CRYPTO_ZUC          0x00190000
+#define SAB_CW0_CRYPTO_CHACHA20     0x00110000
+#define SAB_CW0_CRYPTO_SM4          0x001b0000
+#define SAB_CW0_CRYPTO_BC0          0x00190000
+
+/* Hash and authentication algorithm field */
+
+#define SAB_CW0_AUTH_NULL           0x00000000
+#define SAB_CW0_AUTH_HASH_MD5       0x00000000
+#define SAB_CW0_AUTH_HASH_SHA1      0x01000000
+#define SAB_CW0_AUTH_HASH_SHA2_256  0x01800000
+#define SAB_CW0_AUTH_HASH_SHA2_224  0x02000000
+#define SAB_CW0_AUTH_HASH_SHA2_512  0x02800000
+#define SAB_CW0_AUTH_HASH_SHA2_384  0x03000000
+#define SAB_CW0_AUTH_HASH_SHA3_256  0x05800000
+#define SAB_CW0_AUTH_HASH_SHA3_224  0x06000000
+#define SAB_CW0_AUTH_HASH_SHA3_512  0x06800000
+#define SAB_CW0_AUTH_HASH_SHA3_384  0x07000000
+#define SAB_CW0_AUTH_HASH_SM3       0x03800000
+#define SAB_CW0_AUTH_KEYED_HASH_SHA3_256  0x05a00000
+#define SAB_CW0_AUTH_KEYED_HASH_SHA3_224  0x06200000
+#define SAB_CW0_AUTH_KEYED_HASH_SHA3_512  0x06a00000
+#define SAB_CW0_AUTH_KEYED_HASH_SHA3_384  0x07200000
+#define SAB_CW0_AUTH_SSLMAC_SHA1    0x00e00000
+#define SAB_CW0_AUTH_HMAC_MD5       0x00600000
+#define SAB_CW0_AUTH_HMAC_SHA1      0x01600000
+#define SAB_CW0_AUTH_HMAC_SHA2_256  0x01e00000
+#define SAB_CW0_AUTH_HMAC_SHA2_224  0x02600000
+#define SAB_CW0_AUTH_HMAC_SHA2_512  0x02e00000
+#define SAB_CW0_AUTH_HMAC_SHA2_384  0x03600000
+#define SAB_CW0_AUTH_HMAC_SHA3_256  0x05e00000
+#define SAB_CW0_AUTH_HMAC_SHA3_224  0x06600000
+#define SAB_CW0_AUTH_HMAC_SHA3_512  0x06e00000
+#define SAB_CW0_AUTH_HMAC_SHA3_384  0x07600000
+#define SAB_CW0_AUTH_HMAC_SM3       0x03e00000
+#define SAB_CW0_AUTH_CMAC_128       0x00c00000
+#define SAB_CW0_AUTH_CMAC_192       0x01400000
+#define SAB_CW0_AUTH_CMAC_256       0x01c00000
+#define SAB_CW0_AUTH_GHASH          0x02400000
+#define SAB_CW0_AUTH_KASUMI_F9      0x03c00000
+#define SAB_CW0_AUTH_SNOW_UIA2      0x03400000
+#define SAB_CW0_AUTH_ZUC_EIA3       0x02C00000
+#define SAB_CW0_AUTH_POLY1305       0x07800000
+#define SAB_CW0_AUTH_KEYED_HASH_POLY1305 0x07c00000
+
+/* Add this when hash value must be loaded from context */
+#define SAB_CW0_HASH_LOAD_DIGEST    0x00200000
+
+/* SPI present */
+#define SAB_CW0_SPI                 0x08000000
+
+/* Sequence number size */
+#define SAB_CW0_SEQNUM_32           0x10000000
+#define SAB_CW0_SEQNUM_48           0x20000000
+#define SAB_CW0_SEQNUM_64           0x30000000
+/* Sequence number size encodings for 'fixed offset' */
+#define SAB_CW0_SEQNUM_32_FIX       0x00008000
+#define SAB_CW0_SEQNUM_64_FIX       0x10008000
+#define SAB_CW0_SEQNUM_48_FIX       0x20008000
+
+
+/* Mask size */
+#define SAB_CW0_MASK_64             0x40000000
+#define SAB_CW0_MASK_32             0x80000000
+#define SAB_CW0_MASK_128            0xc0000000
+/* Mask size encodings for 'fixed offset' */
+#define SAB_CW0_MASK_64_FIX         0x00008000
+#define SAB_CW0_MASK_128_FIX        0x40008000
+#define SAB_CW0_MASK_256_FIX        0xc0008000
+#define SAB_CW0_MASK_384_FIX        0x80008000
+#define SAB_CW0_MASK_1024_FIX       0x40008000
+#define SAB_CW0_SEQNUM_APPEND       0x00004000
+
+/* Crypto feedback mode */
+#define SAB_CW1_CRYPTO_MODE_ECB      0x00000000
+#define SAB_CW1_CRYPTO_MODE_CBC      0x00000001
+#define SAB_CW1_CRYPTO_MODE_F8_UEA   0x00000001
+#define SAB_CW1_CRYPTO_MODE_CTR      0x00000002
+#define SAB_CW1_CRYPTO_MODE_ICM      0x00000003
+#define SAB_CW1_CRYPTO_MODE_OFB      0x00000004
+#define SAB_CW1_CRYPTO_MODE_CFB      0x00000005
+#define SAB_CW1_CRYPTO_MODE_CTR_LOAD 0x00000006
+#define SAB_CW1_CRYPTO_MODE_XTS      0x00000007
+#define SAB_CW1_CRYPTO_MODE_CHACHA256 0x00000000
+#define SAB_CW1_CRYPTO_MODE_CHACHA128 0x00000001
+#define SAB_CW1_CRYPTO_MODE_CHACHA_CTR32 0x00000002
+#define SAB_CW1_CRYPTO_MODE_CHACHA_CTR64 0x00000000
+#define SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK 0x00000004
+#define SAB_CW1_CRYPTO_AEAD              0x00000008
+#define SAB_CW1_CRYPTO_NONCE_XOR         0x00000010
+
+/* IV words load */
+#define SAB_CW1_IV0                  0x00000020
+#define SAB_CW1_IV1                  0x00000040
+#define SAB_CW1_IV2                  0x00000080
+#define SAB_CW1_IV3                  0x00000100
+
+#define SAB_CW1_DIGEST_CNT           0x00000200
+
+/* IV mode */
+#define SAB_CW1_IV_FULL              0x00000000
+#define SAB_CW1_IV_CTR               0x00000400
+#define SAB_CW1_IV_ORIG_SEQ          0x00000800
+#define SAB_CW1_IV_INCR_SEQ          0x00000c00
+#define SAB_CW1_IV_MODE_MASK         0x00000c00
+
+#define SAB_CW1_CRYPTO_STORE        0x00001000
+
+#define SAB_CW1_PREPKT_OP           0x00002000
+
+/* Pad type */
+#define SAB_CW1_PAD_ZERO            0x00000000
+#define SAB_CW1_PAD_PKCS7           0x00004000
+#define SAB_CW1_PAD_CONST           0x00008000
+#define SAB_CW1_PAD_RTP             0x0000c000
+#define SAB_CW1_PAD_IPSEC           0x00010000
+#define SAB_CW1_PAD_TLS             0x00014000
+#define SAB_CW1_PAD_SSL             0x00018000
+#define SAB_CW1_PAD_IPSEC_NOCHECK   0x0001c000
+
+
+#define SAB_CW1_ENCRYPT_HASHRES     0x00020000
+#define SAB_CW1_MACSEC_SEQCHECK     0x00040000
+#define SAB_CW1_WIRELESS_DIR        0x00040000
+#define SAB_CW1_HASH_STORE          0x00080000
+
+#define SAB_CW1_EXT_CIPHER_SET      0x00100000
+#define SAB_CW1_ARC4_IJ_PTR         0x00100000
+#define SAB_CW1_ARC4_STATE_SEL      0x00200000
+#define SAB_CW1_CCM_IV_SHIFT        0x00200000
+#define SAB_CW1_XTS_STATEFUL        0x00200000
+#define SAB_CW1_SEQNUM_STORE        0x00400000
+#define SAB_CW1_NO_MASK_UPDATE      0x00800000
+#define SAB_CW1_EARLY_SEQNUM_UPDATE 0x40000000
+#define SAB_CW1_CNTX_FETCH_MODE     0x80000000
+
+#define SAB_SEQNUM_LO_FIX_OFFSET    32
+#define SAB_SEQNUM_HI_FIX_OFFSET    48
+
+
+/* Flag byte for CCM. first byte in counter mode IV, equal to L-1.
+ */
+#define SAB_CCM_FLAG_L4             0x3
+#define SAB_CCM_FLAG_L3             0x2
+
+/* This structure represents the internal state of the SA builder, shared
+   between all sub-functions, e.g. for encryption, hash and protocol-specific
+   extensions.
+ */
+typedef struct
+{
+    unsigned int CurrentOffset; /* Current word offset within the SA */
+    uint32_t CW0; /* Control word 0 */
+    uint32_t CW1; /* Control word 1 */
+    unsigned int CipherKeyWords; /* Size of the cipher key in words */
+    unsigned int IVWords; /* Size of the IV in words */
+    bool ARC4State; /* Is ARC4 state used? */
+    bool fLarge; /* Is this a large transform record? */
+    bool fLargeMask; /* Do we use a large sequence number mask? */
+} SABuilder_State_t;
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMat
+ *
+ * Copy a key into the SA
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the SA record.
+ * offset (input)
+ *   Word offset of the key in the SA record where it must be stored.
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMat(uint32_t * const Destination_p,
+                        const unsigned int offset,
+                        const uint8_t * const Source_p,
+                        const unsigned int KeyByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMatSwap
+ *
+ * Copy a key into the SA with the words byte-swapped.
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) to store the data.
+ * offset (input)
+ *   Word offset of the key in the SA record where it must be stored.
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMatSwap(uint32_t * const Destination_p,
+                            const unsigned int offset,
+                            const uint8_t * const Source_p,
+                            const unsigned int KeyByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_ZeroFill
+ *
+ * Fill an area in the SA with zero bytes.
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the SA record.
+ *
+ * offset (input)
+ *   Word offset of the area in the SA that must be zero-filled.
+ *
+ * ByteCount (input)
+ *   Number of bytes to write.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no zeroes
+ * will be written.
+ */
+void
+SABuilderLib_ZeroFill(
+        uint32_t * const Destination_p,
+        const unsigned int offset,
+        const unsigned int ByteCount);
+
+#ifdef SAB_ENABLE_PROTO_BASIC
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSSLTLSParams
+ *
+ * Fill in Basic Crypto and hash specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetBasicParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p);
+
+#endif
+
+
+#ifdef SAB_ENABLE_PROTO_IPSEC
+/*----------------------------------------------------------------------------
+ * SABuilder_SetIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetIPsecParams(SABuilder_Params_t *const SAParams_p,
+                         SABuilder_State_t * const SAState_p,
+                         uint32_t * const SABuffer_p);
+
+#endif
+
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSSLTLSParams
+ *
+ * Fill in SSL/TLS/DTLS-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSSLTLSParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p);
+
+#endif
+
+
+#ifdef SAB_ENABLE_PROTO_SRTP
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSRTPParams
+ *
+ * Fill in SRTP-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSRTPParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p);
+
+#endif
+
+
+#ifdef SAB_ENABLE_PROTO_MACSEC
+/*----------------------------------------------------------------------------
+ * SABuilder_SetMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetMACsecParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p);
+
+#endif
+
+
+
+#endif /* SA_BUILDER_INTERNAL_H_ */
+
+
+/* end of file sa_builder_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ipsec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ipsec.h
new file mode 100644
index 0000000..fb4d8e5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ipsec.h
@@ -0,0 +1,87 @@
+/* sa_builder_ipsec.h
+ *
+ * IPsec specific functions of the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef  SA_BUILDER_IPSEC_H_
+#define SA_BUILDER_IPSEC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+#include "sa_builder.h"
+#include "sa_builder_params_ipsec.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_ESP
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_IPsec_t extension with sensible defaults for ESP
+ * processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsIPsec_p (output)
+ *   Pointer to IPsec parameter extension to be filled in
+ * spi (input)
+ *   SPI of the newly created parameter structure (must not be zero).
+ * TunnelTransport (input)
+ *   Must be one of SAB_IPSEC_TUNNEL or SAB_IPSEC_TRANSPORT.
+ * IPMode (input)
+ *   Must be one of SAB_IPSEC_IPV4 or SAB_IPSEC_IPV6.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL, which is illegal according to the IPsec standards, but it is
+ * possible to use this setting for debug purposes.
+ *
+ * Both the SAParams_p and SAParamsIPsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsIPsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_ESP(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_IPsec_t * const SAParamsIPsec_p,
+    const uint32_t spi,
+    const uint32_t TunnelTransport,
+    const uint32_t IPMode,
+    const SABuilder_Direction_t direction);
+
+
+#endif /* SA_BUILDER_IPSEC_H_ */
+
+
+/* end of file sa_builder_ipsec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_macsec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_macsec.h
new file mode 100644
index 0000000..7036397
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_macsec.h
@@ -0,0 +1,86 @@
+/* sa_builder_macsec.h
+ *
+ * MACsec specific functions of the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef  SA_BUILDER_MACSEC_H_
+#define SA_BUILDER_MACSEC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+#include "sa_builder.h"
+#include "sa_builder_params_macsec.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_MACsec
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_MACsec_t extension with sensible defaults for MACsec
+ * processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsMACsec_p (output)
+ *   Pointer to MACsec parameter extension to be filled in
+ * SCI_p (input)
+ *   Pointer to Secure Channel Identifier, 8 bytes.
+ * AN (input)
+ *   Association number, a number for 0 to 3.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsMACsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsMACsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_MACsec(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_MACsec_t * const SAParamsMACsec_p,
+    const uint8_t *SCI_p,
+    const uint8_t AN,
+    const SABuilder_Direction_t direction);
+
+
+#endif /* SA_BUILDER_MACSEC_H_ */
+
+
+/* end of file sa_builder_macsec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params.h
new file mode 100644
index 0000000..5f1b77e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params.h
@@ -0,0 +1,315 @@
+/* sa_builder_params.h
+ *
+ * Type definitions for the parameter structure for the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_H_
+#define SA_BUILDER_PARAMS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* This specifies one of the supported protocols. For each of the
+ * supported protocols, the SABuilder_Params_t record contains a
+ * protocol-specific extension, defined in a separate header file.
+ */
+typedef enum
+{
+    SAB_PROTO_BASIC,
+    SAB_PROTO_IPSEC,
+    SAB_PROTO_SSLTLS,
+    SAB_PROTO_MACSEC,
+    SAB_PROTO_SRTP
+} SABuilder_Protocol_t;
+
+/* Specify direction: outbound (encrypt) or inbound (decrypt) */
+typedef enum
+{
+    SAB_DIRECTION_OUTBOUND,
+    SAB_DIRECTION_INBOUND
+} SABuilder_Direction_t;
+
+/* Values for the flags field. Combine any values using a bitwise or.
+   If no flags apply, use the value zero. */
+#define SAB_FLAG_GATHER            BIT_0
+#define SAB_FLAG_SCATTER           BIT_1
+#define SAB_FLAG_SUPPRESS_HDRPROC  BIT_2
+#define SAB_FLAG_SUPPRESS_HEADER   BIT_3
+#define SAB_FLAG_SUPPRESS_PAYLOAD  BIT_4
+
+#define SAB_FLAG_IV_SAVE           BIT_5 /* Save IV back into SA */
+#define SAB_FLAG_ARC4_STATE_SAVE   BIT_6 /* Save ARCFOUR state back */
+#define SAB_FLAG_ARC4_STATE_LOAD   BIT_7 /* Load ARCFOUR state */
+#define SAB_FLAG_HASH_LOAD         BIT_8 /* Load digest value from SA */
+#define SAB_FLAG_HASH_SAVE         BIT_9 /* Save digest value into SA */
+#define SAB_FLAG_HASH_INTERMEDIATE BIT_10 /* hash message crosses multiple
+                                   packets: load/store intermediate digest */
+#define SAB_FLAG_COPY_IV           BIT_11 /* Insert the IV into the output packet (basic crypto) */
+#define SAB_FLAG_REDIRECT          BIT_12 /* Redirect packets to other interface*/
+
+
+/* Specify one of the crypto algorithms */
+typedef enum
+{
+    SAB_CRYPTO_NULL,
+    SAB_CRYPTO_DES,
+    SAB_CRYPTO_3DES,
+    SAB_CRYPTO_AES,
+    SAB_CRYPTO_ARCFOUR,
+    SAB_CRYPTO_KASUMI,
+    SAB_CRYPTO_SNOW,
+    SAB_CRYPTO_ZUC,
+    SAB_CRYPTO_CHACHA20,
+    SAB_CRYPTO_SM4,
+    SAB_CRYPTO_BC0, /* Auxiliary block cipher algorithm */
+} SABuilder_Crypto_t;
+
+/* Specify one of the crypto modes */
+typedef enum
+{
+    SAB_CRYPTO_MODE_ECB,
+    SAB_CRYPTO_MODE_CBC,
+    SAB_CRYPTO_MODE_OFB,
+    SAB_CRYPTO_MODE_CFB,
+    SAB_CRYPTO_MODE_CFB1,
+    SAB_CRYPTO_MODE_CFB8,
+    SAB_CRYPTO_MODE_CTR,
+    SAB_CRYPTO_MODE_ICM,
+    SAB_CRYPTO_MODE_CCM,       /* Only use with AES, set SAB_AUTH_AES_CCM */
+    SAB_CRYPTO_MODE_GCM,       /* Only use with AES, set SAB_AUTH_AES_GCM */
+    SAB_CRYPTO_MODE_GMAC,      /* Only use with AES, set SAB_AUTH_AES_GMAC */
+    SAB_CRYPTO_MODE_STATELESS, /* For ARC4 */
+    SAB_CRYPTO_MODE_STATEFUL, /* For ARC4 */
+    SAB_CRYPTO_MODE_XTS,      /* Only use with AES, no authentication */
+    SAB_CRYPTO_MODE_XTS_STATEFUL, /* Only use with AES, no authentication.
+                                   Stateful operation, allow multiple
+                                   operations on the same 'sector' */
+    SAB_CRYPTO_MODE_BASIC,
+    SAB_CRYPTO_MODE_F8,       /* Only with Kasumi */
+    SAB_CRYPTO_MODE_UEA2,     /* Only with SNOW */
+    SAB_CRYPTO_MODE_EEA3,     /* Only with ZUC */
+    SAB_CRYPTO_MODE_CHACHA_CTR32, /* Only with Chacha20 */
+    SAB_CRYPTO_MODE_CHACHA_CTR64, /* Only with Chacha20 */w
+} SABuilder_Crypto_Mode_t;
+
+/* Specify one of the IV sources. Not all methods are supported with all
+ protocols.*/
+typedef enum
+{
+    SAB_IV_SRC_DEFAULT, /* Default mode for the protocol */
+    SAB_IV_SRC_SA,      /* IV is loaded from SA */
+    SAB_IV_SRC_PRNG,    /* IV is derived from PRNG */
+    SAB_IV_SRC_INPUT,   /* IV is prepended to the input packet. */
+    SAB_IV_SRC_TOKEN,   /* IV is included in the packet token. */
+    SAB_IV_SRC_SEQ,     /* IV is derived from packet sequence number. */
+    SAB_IV_SRC_XORSEQ,  /* IV is derived from packet sequence number XOR-ed
+                           with fixed value. */
+    SAB_IV_SRC_IMPLICIT, /* IV is derived from packet sequence number,
+                            not included in packet data (RFC8750 for ESP) */
+} SABuilder_IV_Src_t;
+
+/* Specify one of the hash or authentication methods */
+typedef enum
+{
+    SAB_AUTH_NULL,
+    SAB_AUTH_HASH_MD5,
+    SAB_AUTH_HASH_SHA1,
+    SAB_AUTH_HASH_SHA2_224,
+    SAB_AUTH_HASH_SHA2_256,
+    SAB_AUTH_HASH_SHA2_384,
+    SAB_AUTH_HASH_SHA2_512,
+    SAB_AUTH_SSLMAC_MD5,
+    SAB_AUTH_SSLMAC_SHA1,
+    SAB_AUTH_HMAC_MD5,
+    SAB_AUTH_HMAC_SHA1,
+    SAB_AUTH_HMAC_SHA2_224,
+    SAB_AUTH_HMAC_SHA2_256,
+    SAB_AUTH_HMAC_SHA2_384,
+    SAB_AUTH_HMAC_SHA2_512,
+    SAB_AUTH_AES_XCBC_MAC,
+    SAB_AUTH_AES_CMAC_128,  /* Identical to AES_XCBC_MAC */
+    SAB_AUTH_AES_CMAC_192,
+    SAB_AUTH_AES_CMAC_256,
+    SAB_AUTH_AES_CCM,      /* Set matching crypto algorithm and mode */
+    SAB_AUTH_AES_GCM,      /* Set matching crypto algorithm and mode */
+    SAB_AUTH_AES_GMAC,     /* Set matching crypto algorithm and mode */
+    SAB_AUTH_KASUMI_F9,
+    SAB_AUTH_SNOW_UIA2,
+    SAB_AUTH_ZUC_EIA3,
+    SAB_AUTH_HASH_SHA3_224,
+    SAB_AUTH_HASH_SHA3_256,
+    SAB_AUTH_HASH_SHA3_384,
+    SAB_AUTH_HASH_SHA3_512,
+    SAB_AUTH_KEYED_HASH_SHA3_224,
+    SAB_AUTH_KEYED_HASH_SHA3_256,
+    SAB_AUTH_KEYED_HASH_SHA3_384,
+    SAB_AUTH_KEYED_HASH_SHA3_512,
+    SAB_AUTH_HMAC_SHA3_224,
+    SAB_AUTH_HMAC_SHA3_256,
+    SAB_AUTH_HMAC_SHA3_384,
+    SAB_AUTH_HMAC_SHA3_512,
+    SAB_AUTH_POLY1305,
+    SAB_AUTH_KEYED_HASH_POLY1305,
+    SAB_AUTH_HASH_SM3,
+    SAB_AUTH_HMAC_SM3,
+} SABuilder_Auth_t;
+
+/* This is the main SA parameter structure.
+ *
+ * This contains the common fields for all protocol families.
+ * Each protocol has a special extension.
+ *
+ * The entire data structure (including protocol-specific extension) must be
+ * prepared before calling SABuilder_GetSizes() and SABuilder_Build_SA().
+ *
+ * See the SABuilder_Init* functions in the protocol specific headers
+ * (sa_builder_ipsec.h etc.) for helper functions to prepare it.
+ * All these initialization functions will provide sensible defaults for all
+ * fields, but both the crypto algorithm and the authentication algorithm
+ * are set to NULL.
+ *
+ * For a practical use, at least the following fields must be filled in
+ * after calling the initialization functions:
+ * - CryptoAlgo, Key_p and KeyByteCount if encryption is required.
+ *   - CryptoMode if anything other than CBC is required.
+ *   - Nonce_p if counter mode is used.
+ * - AuthAlgo if authentication is desired and (depending on the
+ *   authentication algorithm), one or more of
+ *   AuthKey1_p, AuthKey2_p or AuthKey3_p.
+ */
+typedef struct
+{
+    /* Protocol related fields */
+    SABuilder_Protocol_t protocol;
+    SABuilder_Direction_t direction;
+    void * ProtocolExtension_p; /* Pointer to the extension record */
+    uint32_t flags; /* Generic flags */
+
+    /* Crypto related fields */
+    SABuilder_Crypto_t CryptoAlgo; /* Cryptographic algorithm */
+    SABuilder_Crypto_Mode_t CryptoMode;
+    uint8_t CryptoParameter; /* Additional algorithm parameter,
+                                for example number of rounds */
+    SABuilder_IV_Src_t IVSrc; /* source of IV */
+    uint8_t KeyByteCount; /* Key length in bytes */
+    uint8_t *Key_p;    /* pointer to crypto key */
+    uint8_t *IV_p;     /* pointer to initialization vector.
+                          IV size is implied by crypto algorithm and mode */
+    uint8_t *Nonce_p;    /* Cryptographic nonce, e.g. for counter mode */
+    /* Note: for ARCFOUR, the stream cipher state will be loaded if the
+       SAB_FLAG_ARC4_STATE_LOAD flag is set.
+       Nonce_p[0] is the I variable, Nonce_p[1] is the J variable and
+       IV_p points to the 256-byte S-array.
+
+       If this flag is not set, the stream cipher state will not be
+       loaded at SA build time and the first packet has to specify
+       the ARCFOUR state to be initialized from the key.
+
+       For AES-XTS, the Nonce represents Key2, */
+
+    /* Authentication related fields */
+    SABuilder_Auth_t AuthAlgo; /* Authentication algorithm */
+    uint8_t AuthKeyByteCount; /* Number of bytes in authentication key
+                                 (only used for keyed SHA3 and HMAC-SHA3) */
+    uint8_t *AuthKey1_p;
+    uint8_t *AuthKey2_p;
+    uint8_t *AuthKey3_p;
+    /* The SA Builder expects authentication keys in their
+       preprocessed form. The sizes of the authentication keys are
+       implied by AuthAlgo. For details on the preprocessed
+       authentication keys, see the Implementation Notes document.
+
+       Plain hash functions with no digest loading:
+                   No authentication keys are used.
+       Plain hash functions with digest loading:
+                   AuthKey1 is the digest to be loaded.
+       Any of the HMAC functions:
+                   AuthKey1 is precomputed inner digest.
+                   AuthKey2 is precomputed outer digest.
+       SSL-MAC-MD$:
+                   AuthKey1 is precomputed inner digest.
+                   AuthKey2 is precomputed outer digest.
+       SSL-HAC-SHA1:
+                   AuthKey1 is the authentication key (not pre-processed).
+       GCM or GMAC:
+                   AuthKey1 is H = E(K,0). This is an all-zero block encrypted
+                   with the encryption key.
+       XCBC_MAC (RFC3566):
+                   AuthKey1 = K1
+                   AuthKey2 = K2
+                   AuthKey3 = K3
+       CMAC (RFC4493,RFC4494):
+                   AuthKey1 = K
+                   AuthKey2 = K1
+                   AuthKey3 = K2
+       CCM:
+                   No authentication keys required: the SA builder will
+                   use the encryption key.
+
+       Unused AuthKey fields may be NULL.
+    */
+    uint8_t RedirectInterface;
+    /* Interface ID to which packets must be redirected */
+
+    uint32_t OffsetARC4StateRecord;
+    /* Offset of the ARC4 State record with respect to the start of
+       the SA record. The application can set this to specify a
+       desired offset for this record. If left 0, the SA Builder will
+       put the ARC4 state right after the SA.
+
+       This parameter is only used when SAB_ARC4_STATE_IN_SA is defined.
+    */
+
+    /* The following values reflect control words. The application shall
+       not touch those */
+    uint32_t CW0, CW1;
+
+    /* The following values reflect. offsets of certain fields in the SA
+     buffer. The application shall not touch these.*/
+    uint8_t OffsetDigest0; /* Word-offset of Digest 0 */
+    uint8_t OffsetDigest1; /* Word-offset of Digest 1 */
+    uint8_t OffsetSeqNum;  /* Word-offset of Sequence Number  */
+    uint8_t OffsetSeqMask; /* Word-offset of Sequence Number Mask */
+    uint8_t OffsetIV;      /* Word-offset of IV */
+    uint8_t OffsetIJPtr;   /* Word-offset of IJ Pointer for ARC4 */
+    uint8_t OffsetARC4State; /* Word-offset of ARC4 state */
+    /* The following values reflect the width of certain fields in the SA
+       (those that may be updated and may be read back)*/
+    uint8_t SeqNumWord32Count; /* Width of the sequence number */
+    uint8_t SeqMaskWord32Count;/* Width of the sequence number masks*/
+    uint8_t IVWord32Count;  /* Width of the IV */
+} SABuilder_Params_t;
+
+
+#endif /* SA_BUILDER_PARAMS_H_ */
+
+
+/* end of file sa_builder_params.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_basic.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_basic.h
new file mode 100644
index 0000000..3cfead3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_basic.h
@@ -0,0 +1,78 @@
+/* sa_builder_params_basic.h
+ *
+ * Basic crypto and hash specific extension to the SABuilder_Params_t type.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_BASIC_H_
+#define SA_BUILDER_PARAMS_BASIC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/* Flag bits for the BasicFlags field. Combine any values using a
+   bitwise or.
+ */
+#define SAB_BASIC_FLAG_EXTRACT_ICV   BIT_0 /* Extract and verify ICV from packet*/
+#define SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH BIT_1
+/* Encrypt the hashed data (default is hashing the encrypted data). */
+#define SAB_BASIC_FLAG_HMAC_PRECOMPUTE BIT_2
+/* Special operation to precompute HMAC keys */
+#define SAB_BASIC_FLAG_XFRM_API BIT_3
+/* Specify bypass operation for XFRM API */
+
+
+/* Extension record for SAParams_t. Protocol_Extension_p must point
+   to this structure when the Basic crypto/hash protocol is used.
+
+   SABuilder_Iinit_Basic() will fill all fields in this structure  with
+   sensible defaults.
+ */
+
+typedef struct
+{
+    uint32_t BasicFlags;
+    uint32_t DigestBlockCount;
+    uint32_t ICVByteCount; /* Length of ICV in bytes. */
+    uint32_t  fresh;      /* 32-bit 'fresh' value for wireless authentication
+                             algorithms. */
+    uint8_t bearer;       /* 5-bit 'bearer' value for wireless algorithms. */
+    uint8_t direction;   /* 1-bit 'direction' value for wireless algorithms. */
+    uint32_t ContextRef; /* Reference to application context */
+} SABuilder_Params_Basic_t;
+
+
+#endif /* SA_BUILDER_PARAMS_BASIC_H_ */
+
+
+/* end of file sa_builder_params_basic.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ipsec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ipsec.h
new file mode 100644
index 0000000..61c89a9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ipsec.h
@@ -0,0 +1,136 @@
+/* sa_builder_params_ipsec.h
+ *
+ * IPsec specific extension to the SABuilder_Params_t type.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_IPSEC_H_
+#define SA_BUILDER_PARAMS_IPSEC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+#define SA_SEQ_MASK_WORD_COUNT 12 /* Maximum number of words in sequence mask */
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Flag bits for the IPsecFlags field. Combine any values using a
+   bitwise or.
+   Of SAB_IPSEC_ESP and SAB_AH, exactly one must be set.
+   Of SAB_IPSEC_TUNNEL and SAB_IPSEC_TRANSPORT, exactly one must be set.
+   Of SAB_IPSEC_IPV4 and SAB_IPSEC_IPV6, exactly one must be set.
+*/
+
+#define SAB_IPSEC_ESP             BIT_0
+#define SAB_IPSEC_AH              BIT_1
+
+#define SAB_IPSEC_TUNNEL          BIT_2
+#define SAB_IPSEC_TRANSPORT       BIT_3
+
+#define SAB_IPSEC_IPV4            BIT_4
+#define SAB_IPSEC_IPV6            BIT_5
+
+#define SAB_IPSEC_LONG_SEQ        BIT_6 /* Use 64-bit extended seq. number */
+#define SAB_IPSEC_NO_ANTI_REPLAY  BIT_7 /* Disable anti-replay protection */
+#define SAB_IPSEC_MASK_128        BIT_8 /* Use 128-bit anti-replay mask instead of 64-bit (for downward compatibility) */
+#define SAB_IPSEC_MASK_32         BIT_9 /* Use 32-bit anti-replay mask instead of 64-bit (for downward compatibility) */
+
+#define SAB_IPSEC_PROCESS_IP_HEADERS BIT_10 /* Perform header processing */
+#define SAB_IPSEC_CLEAR_DF        BIT_11 /* Clear DF on outer tunnel header */
+#define SAB_IPSEC_SET_DF          BIT_12 /* Set DF on outer tunnel header */
+#define SAB_IPSEC_NATT            BIT_13 /* Encapsulate ESP in UDP for nat traversal */
+#define SAB_IPSEC_REPLACE_DSCP    BIT_14 /* Copy DSCP from transform record */
+#define SAB_IPSEC_MASK_384        BIT_15 /* Use 384-bit anti-replay mask instead of 64-bit (for downward compatibility) */
+#define SAB_IPSEC_APPEND_SEQNUM   BIT_16 /* Cause the hardware to append sequence number to output */
+#define SAB_IPSEC_CLEAR_ECN       BIT_17 /* Clear ECN bits in tunnel header for compatibility mode */
+#define SAB_IPSEC_MASK_256        BIT_18 /* Use 256-bit anti-replay mask instead of 64-bit (for downward compatibility) */
+#define SAB_IPSEC_FIXED_SEQ_OFFSET BIT_19 /* Use fixed sequence number offset
+                                             for 64 or 128 bit masks. */
+#define SAB_IPSEC_EXT_PROCESSING  BIT_20 /* Extended processing for IPsec
+                                            in stand-alone token builder */
+#define SAB_IPSEC_TRANSPORT_NAT     BIT_21 /* Use additional NAT with transport NATT */
+#define SAB_IPSEC_CHECKSUM_FIX      BIT_22 /* Fix checksum for inbound transport NAT-T */
+#define SAB_IPSEC_DEC_TTL           BIT_23 /* Decrement TTL/hop limit field */
+
+#define SAB_IPSEC_XFRM_API          BIT_24 /* Use this transform with Linux kernel XFRM API */
+
+/* Extension record for SAParams_t. Protocol_Extension_p must point
+   to this structure when the IPsec protocol is used.
+
+   SABuilder_Iinit_ESP() will fill all fields in this structure  with
+   sensible defaults.
+ */
+typedef struct
+{
+    uint32_t spi;
+    uint32_t IPsecFlags;    /* See SAB_IPSEC_* flag bits above */
+
+    uint32_t SeqNum;       /* Initialize with zero */
+    uint32_t SeqNumHi;     /* Only valid if SAB_IPSEC_LONG_SEQ is set */
+    uint32_t SeqMask[SA_SEQ_MASK_WORD_COUNT];
+                           /* Mask window Only used with inbound operations.
+                              By default, set first word to 1, all others to 0.
+
+                              The mask can be programmed to resume an existing
+                              SA operation, This field is unused for
+                              mask sizes that cannot be accommodated in
+                              this array. For these, only the default mask is
+                              possible,
+                           */
+    uint32_t PadAlignment; /* Align padding to specified multiple of bytes.
+                              This must be a power of two between 4 and 256.
+                              If zero, default pad alignment is used.*/
+    uint32_t ICVByteCount; /* Length of ICV in bytes. If left zero, a default
+                              value is used, compatible with the authentication
+                              algorithm, */
+    uint8_t *SrcIPAddr_p;  /* Source IP address for tunnel header.
+                                 4 bytes for IPv4, 16 bytes for IPv6
+                              Also used as the translate-to address for NAT.*/
+    uint8_t *DestIPAddr_p; /* Destination IP address for tunnel header.
+                              4 bytes for IPv4, 16 bytes for IPv6
+                              Also used as the translate-to address for NAT.*/
+    uint8_t *OrigSrcIPAddr_p; /* Original NAT source address (translate-from)
+                                 used in checksum delta calculations */
+    uint8_t *OrigDestIPAddr_p; /* Original NAT destination address (translate-from)
+                                 used in checksum delta calculations */
+    uint16_t NATTSrcPort;  /* UDP source port when using NAT-T */
+    uint16_t NATTDestPort; /* UDP destination port when using NAT-T */
+    uint32_t ContextRef; /* Reference to application context */
+    uint8_t  TTL;        /* Time-to-live/Hop Limit in outer header */
+    uint8_t  DSCP;       /* DSCP/traffic class field in outer header
+                            if copied from SA */
+    uint16_t SequenceMaskBitCount; /* Number of bits in sequence number mask.
+                                      Default is 64 */
+} SABuilder_Params_IPsec_t;
+
+
+#endif /* SA_BUILDER_PARAMS_IPSEC_H_ */
+
+
+/* end of file sa_builder_params_ipsec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_macsec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_macsec.h
new file mode 100644
index 0000000..65b9d91
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_macsec.h
@@ -0,0 +1,75 @@
+/* sa_builder_params_macsec.h
+ *
+ * MACsec specific extension to the SABuilder_Params_t type.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_MACSEC_H_
+#define SA_BUILDER_PARAMS_MACSEC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Flag bits for the MACsecFlags field. Combine any values using a
+   bitwise or.
+ */
+#define SAB_MACSEC_ES              BIT_0 /* End Station */
+#define SAB_MACSEC_SC              BIT_1 /* Include SCI in frames */
+#define SAB_MACSEC_SCB             BIT_2 /* Enable EPON Single Channel Broadcase */
+
+
+/* Extension record for SAParams_t. Protocol_Extension_p must point
+   to this structure when the MACsec  protocol is used.
+
+   SABuilder_Iinit_MACsec() will fill all fields in this structure  with
+   sensible defaults.
+ */
+typedef struct
+{
+    uint32_t MACsecFlags;  /* See SAB_MACSEC_* flag bits above*/
+    const uint8_t *SCI_p;        /* Pointer to 8-byte SCI */
+    uint8_t AN;            /* Association Number */
+
+    uint32_t SeqNum;       /* Sequence number.*/
+
+    uint32_t ReplayWindow; /* Size of the anti-replay window */
+
+    uint32_t ConfOffset; /* Confidentiality Offset. Specify a number of
+                                unencrypted bytes at the start of each packet.*/
+    uint32_t ContextRef; /* Reference to application context */
+} SABuilder_Params_MACsec_t;
+
+
+#endif /* SA_BUILDER_PARAMS_MACSEC_H_ */
+
+
+/* end of file sa_builder_params_macsec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_srtp.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_srtp.h
new file mode 100644
index 0000000..6751a10
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_srtp.h
@@ -0,0 +1,65 @@
+/* sa_builder_params_srtp.h
+ *
+ * SRTP specific extension to the SABuilder_Params_t type.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_SRTP_H_
+#define SA_BUILDER_PARAMS_SRTP_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Flag values for te SRTPFlags field */
+#define SAB_SRTP_FLAG_SRTCP          BIT_0
+#define SAB_SRTP_FLAG_INCLUDE_MKI    BIT_1
+
+
+/* Extension record for SAParams_t. Protocol_Extension_p must point
+   to this structure when the SRTP protocol is used.
+
+   SABuilder_Iinit_SRTP() will fill all fields in this structure  with
+   sensible defaults.
+ */
+typedef struct
+{
+    uint32_t SRTPFlags;
+    uint32_t MKI;
+    uint32_t ICVByteCount; /* Length of ICV in bytes. */
+} SABuilder_Params_SRTP_t;
+
+
+#endif /* SA_BUILDER_PARAMS_SRTP_H_ */
+
+
+/* end of file sa_builder_params_srtp.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ssltls.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ssltls.h
new file mode 100644
index 0000000..1dc79dc
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_params_ssltls.h
@@ -0,0 +1,102 @@
+/* sa_builder_params_ssltls.h
+ *
+ * SSL/TLS/DTLS specific extension to the SABuilder_Params_t type.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef SA_BUILDER_PARAMS_SSLTLS_H_
+#define SA_BUILDER_PARAMS_SSLTLS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Flag bits for the SSLTLSFlags field. Combine any values using a
+   bitwise or.
+ */
+#define SAB_DTLS_NO_ANTI_REPLAY  BIT_0 /* Disable anti-replay protection */
+#define SAB_DTLS_MASK_128        BIT_1 /* Use 128-bit anti-replay mask instead of 64-bit (for downward compatibility)*/
+#define SAB_DTLS_MASK_32         BIT_2 /* Use 32-bit anti-replay mask instead of 64-bit (for downward compatibility)*/
+#define SAB_DTLS_IPV4            BIT_3 /* DLTS transported over UDP IPv4 */
+#define SAB_DTLS_IPV6            BIT_4 /* DTLS transported over UDP IPv6 */
+#define SAB_DTLS_UDPLITE         BIT_5 /* Use UDPLite instead of UDP */
+#define SAB_DTLS_CAPWAP          BIT_6 /* Use CAPWAP/DTLS */
+#define SAB_DTLS_PROCESS_IP_HEADERS BIT_7 /* Perform header processing */
+#define SAB_DTLS_PLAINTEXT_HEADERS BIT_8 /* Expect DTLS headers in plaintext packets */
+#define SAB_DTLS_FIXED_SEQ_OFFSET BIT_9 /* Use fixed sequence number offset
+                                             for 64 or 128 bit masks. */
+#define SAB_DTLS_EXT_PROCESSING  BIT_10 /* Extended processing for DTLS
+                                            in stand-alone token builder */
+
+/* SSL, TLS and DTLS versions */
+#define SAB_SSL_VERSION_3_0   0x0300
+#define SAB_TLS_VERSION_1_0   0x0301
+#define SAB_TLS_VERSION_1_1   0x0302
+#define SAB_TLS_VERSION_1_2   0x0303
+#define SAB_TLS_VERSION_1_3   0x0304
+#define SAB_DTLS_VERSION_1_0  0xFEFF
+#define SAB_DTLS_VERSION_1_2  0xFEFD
+
+/* Extension record for SAParams_t. Protocol_Extension_p must point
+   to this structure when the SSL, TLS or DTLS  protocol is used.
+
+   SABuilder_Iinit_SSLTLS() will fill all fields in this structure  with
+   sensible defaults.
+ */
+typedef struct
+{
+    uint32_t SSLTLSFlags;  /* See SAB_{SSL,TLS,DTLS}_* flag bits above*/
+    uint16_t version;
+    uint16_t epoch;        /* for DTLS only */
+
+    uint32_t SeqNum;       /* Least significant part of sequence number.*/
+    uint32_t SeqNumHi;     /* Most significant part of sequence number. */
+
+    uint32_t SeqMask[12];   /* Up to 384-bit mask window
+                              Only used with inbound DTLS.
+                              Initialize first word with 1, others with 0. */
+
+    uint32_t PadAlignment; /* Align padding to specified multiple of bytes.
+                              This must be a power of two between 4 and 256.
+                              If zero, default pad alignment is used.*/
+    uint32_t ContextRef; /* Reference to application context */
+    uint16_t SequenceMaskBitCount; /* Number of bits in sequence number mask.
+                                      Default is 64 */
+    uint16_t ICVByteCount; /* Length of ICV in bytes. If left zero, a default
+                              value is used, compatible with the authentication
+                              algorithm, */
+} SABuilder_Params_SSLTLS_t;
+
+
+#endif /* SA_BUILDER_PARAMS_TLS_H_ */
+
+
+/* end of file sa_builder_params_ssltls.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_srtp.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_srtp.h
new file mode 100644
index 0000000..2d8c848
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_srtp.h
@@ -0,0 +1,82 @@
+/* sa_builder_srtp.h
+ *
+ * SRTP specific functions of the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef  SA_BUILDER_SRTP_H_
+#define SA_BUILDER_SRTP_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+#include "sa_builder.h"
+#include "sa_builder_params_srtp.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SRTP
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_SRTP_t extension with sensible defaults for
+ * SRTP processing..
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsSRTP_p (output)
+ *   Pointer to SRTP parameter extension to be filled in
+ * IsSRTCP (input)
+ *   true if the SA is for SRTCP.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Tis function initializes the authentication algorithm to HMAC_SHA1.
+ * The application has to fill in the appropriate keys. The crypto algorithm
+ * is initialized to NULL. It can be changed to AES ICM and then a crypto
+ * key has to be added as well.
+ *
+ * Both the SAParams_p and SAParamsSRTP_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSRTP_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SRTP(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_SRTP_t * const SAParamsSRTP_p,
+    const bool IsSRTCP,
+    const SABuilder_Direction_t direction);
+
+
+#endif /* SA_BUILDER_SRTP_H_ */
+
+
+/* end of file sa_builder_srtp.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ssltls.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ssltls.h
new file mode 100644
index 0000000..971588d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/sa/sa_builder_ssltls.h
@@ -0,0 +1,84 @@
+/* sa_builder_ssltls.h
+ *
+ * SSL/TLS/DTLS specific functions of the SA Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef  SA_BUILDER_SSLTLS_H_
+#define SA_BUILDER_SSLTLS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+#include "sa_builder.h"
+#include "sa_builder_params_ssltls.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SSLTLS
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_SSLTLS_t extension with sensible defaults for SSL, TLS
+ * and DTLS processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsSSLTLS_p (output)
+ *   Pointer to SSLTLS parameter extension to be filled in
+ * version (input)
+ *   Version code for the desired protcol (choose one of the SAB_*_VERSION_*
+ *   constants from sa_builder_params_ssltls.h).
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsSSLTLS_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSSSLTLS_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SSLTLS(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_SSLTLS_t * const SAParamsSSLTLS_p,
+    const uint16_t version,
+    const SABuilder_Direction_t direction);
+
+
+#endif /* SA_BUILDER_SSLTLS_H_ */
+
+
+/* end of file sa_builder_ssltls.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/c_token_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/c_token_builder.h
new file mode 100644
index 0000000..5052c5b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/c_token_builder.h
@@ -0,0 +1,157 @@
+/* c_token_builder.h
+ *
+ * Default configuration file for the Token Builder
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * Import the product specific configuration.
+ */
+#include "cs_token_builder.h"
+
+/* Uncomment this option if the EIP-96 does not use an input packet pointer.
+   This is the case when it is used in a system in which packet data is fetched
+   outside the control of the EIP-96. Whether this setting is needed depends
+   on the hardware environment in which the EIP-96 is integrated.
+ */
+//#define TKB_NO_INPUT_PACKET_POINTER
+
+/* Uncomment this option if context reuse must be auto-detected. This
+   is only supported in EIP-96 HW2.1 and higher.
+ */
+//#define TKB_AUTODETECT_CONTEXT_REUSE
+
+/* Define this to a nonzero value if the generated token must contain a header
+   that includes the Token Header Word. Any other fields are filled with zero.
+   This parameter specifies the header size in words.
+ */
+#ifndef TKB_TOKEN_HEADER_WORD_COUNT
+#define TKB_TOKEN_HEADER_WORD_COUNT 0
+#endif
+
+
+/* Which protocol families are enabled? */
+//#define TKB_ENABLE_PROTO_BASIC
+//#define TKB_ENABLE_PROTO_IPSEC
+//#define TKB_ENABLE_PROTO_SSLTLS
+//#define TKB_ENABLE_PROTO_MACSEC
+//#define TKB_ENABLE_PROTO_SRTP
+
+/* Which protocol-specific options are enabled? */
+//#define TKB_ENABLE_IPSEC_ESP
+//#define TKB_ENABLE_IPSEC_AH
+
+/* Token builder supports extended IPsec operations that include
+ * header processing for ESP tunnel and transport operations.
+*/
+#define TKB_ENABLE_EXTENDED_IPSEC
+
+/* Token builder inserts special instructions to fix up the ECN bits
+   for inbound tunnel protocols. */
+#define TKB_ENABLE_ECN_FIXUP
+
+/* Token builder supports extended DTLS operations that include
+ * IP and UDP header processing.
+*/
+//#define TKB_ENABLE_EXTENDED_DTLS
+
+//#define TKB_ENABLE_CRYPTO_WIRELESS
+//#define TKB_ENABLE_CRYPTO_XTS
+//#define TKB_ENABLE_CRYPTO_CHACHAPOLY
+
+#ifdef TKB_ENABLE_PROTO_BASIC
+#define TKB_HAVE_PROTO_BASIC 1
+#else
+#define TKB_HAVE_PROTO_BASIC 0
+#endif
+
+#ifdef TKB_ENABLE_PROTO_IPSEC
+#define TKB_HAVE_PROTO_IPSEC 1
+#else
+#define TKB_HAVE_PROTO_IPSEC 0
+#undef TKB_ENABLE_EXTENDEDN_IPSEC
+#endif
+
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+#define TKB_HAVE_EXTENDED_IPSEC 1
+#else
+#define TKB_HAVE_EXTENDED_IPSEC 0
+#endif
+
+#ifdef TKB_ENABLE_ECN_FIXUP
+#define TKB_HAVE_ECN_FIXUP 1
+#else
+#define TKB_HAVE_ECN_FIXUP 0
+#endif
+
+#ifdef TKB_ENABLE_EXTENDED_DTLS
+#define TKB_HAVE_EXTENDED_DTLS 1
+#else
+#define TKB_HAVE_EXTENDED_DTLS 0
+#endif
+
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+#define TKB_HAVE_PROTO_SSLTLS 1
+#else
+#define TKB_HAVE_PROTO_SSLTLS 0
+#endif
+
+#ifdef TKB_ENABLE_PROTO_SRTP
+#define TKB_HAVE_PROTO_SRTP 1
+#else
+#define TKB_HAVE_PROTO_SRTP 0
+#endif
+
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+#define TKB_HAVE_CRYPTO_WIRELESS 1
+#else
+#define TKB_HAVE_CRYPTO_WIRELESS 0
+#endif
+
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+#define TKB_HAVE_CRYPTO_CHACHAPOLY 1
+#else
+#define TKB_HAVE_CRYPTO_CHACHAPOLY 0
+#endif
+
+#ifndef TKB_HAVE_CHACHAPOLY_HW30
+#define TKB_HAVE_CHACHAPOLY_HW30 1
+#endif
+
+
+
+#ifdef TKB_ENABLE_CRYPTO_XTS
+#define TKB_HAVE_CRYPTO_XTS 1
+#else
+#define TKB_HAVE_CRYPTO_XTS 0
+#endif
+
+
+/* Strict checking of function arguments if enabled */
+//#define TKB_STRICT_ARGS_CHECK
+
+/* log level for the token builder.
+   choose from LOG_SEVERITY_INFO, LOG_SEVERITY_WARN, LOG_SEVERITY_CRIT */
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_CRIT
+#endif
+
+
+/* end of file c_sa_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder.h
new file mode 100644
index 0000000..3dcd292
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder.h
@@ -0,0 +1,333 @@
+/* token_builder.h
+ *
+ * Token Builder API.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef TOKEN_BUILDER_H_
+#define TOKEN_BUILDER_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "sa_builder_params.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+typedef enum
+{
+    TKB_STATUS_OK,
+    TKB_INVALID_PARAMETER,
+    TKB_BAD_PACKET,
+    TKB_BAD_PROTOCOL,
+    TKB_BAD_FIELD_SIZE,
+    TKB_BAD_CRYPTO,
+    TKB_ERROR,
+} TokenBuilder_Status_t;
+
+/* The Token Context Record is an opaque data structure that holds
+   per-SA information needed by the Token Builder. Its contents are
+   never used outside the Token Builder. The application refers to it
+   via a void pointer and the application shall call
+   TokenBuilder_GetContextSIze() to determine its size and allocate a
+   sufficiently large buffer for it.
+
+   The Token Context Record does not in any way refer to the
+   SABuilder_SA_Params_t record from which it is derived and the
+   latter may safely be discarded after the call to
+   TokenBuilder_BuildContext().
+
+   The Token Context Record is produced by TokenBuilder_BuildContext()
+   and will be used by TokenBuilder_BuildToken(). The application has
+   to make sure that this data structure is not modified and remains
+   allocated as long as it is used. After its last use in a call to
+   TokenBuilder_BuildToken(), it may safely be discarded.
+
+   The Packet Token is a data structure used by some types of packet
+   engine and is required to process the packet correctly. It must be
+   generated separately for every single packet processed.
+
+   The Packet Token is an opaque data structure as far as the application is
+   concerned.. The application refers to it via a void pointer and the
+   application shall call TokenBuilder_GettSIze() to determine its
+   size and allocate a sufficiently large buffer for it..
+
+   A Packet Token has a 32-bit header word, which is returned separately from
+   the main Packet Token data structure.
+
+   The Packet Token must remain allocated until it has been used by
+   the hardware to process that packet.
+*/
+
+/* Per-packet flags */
+
+/* For a basic hash operation, possibly spanning multiple packets,
+ * indicate that this packet is the final one of the hash message
+*/
+#define TKB_PACKET_FLAG_HASHFINAL BIT_0
+
+/* For a basic hash operation, possibly spanning multiple packets,
+ * indicate that this packet is the first one of the hash message
+*/
+#define TKB_PACKET_FLAG_HASHFIRST BIT_1
+
+/* For a basic hash operation, when the message consists of a single
+ * packet, set both TKB_PACKET_FLAG_HASHFIRST and
+ * TKB_PACKET_FLAG_HASHFINAL. For protocols such as IPsec, that always
+ * hash per packet, those flags are not used and should not be set.
+*/
+
+/* Specify that the ARC4 state must be loaded */
+#define TKB_PACKET_FLAG_ARC4_LOAD BIT_2
+
+/* Specify that the ARC4 state must be saved */
+#define TKB_PACKET_FLAG_ARC4_SAVE BIT_3
+
+/* Specify that the initial ARC4 state must be derived from the key.
+   Use this for the first packet encrypted or decrypted by each key, unless
+   the state was loaded by SA Builder.*/
+#define TKB_PARCKET_FLAG_ARC4_INIT BIT_4
+#define TKB_PACKET_FLAG_ARC4_INIT BIT_4
+
+/* Specify that the counter (for counter mode) must be reinitialized */
+#define TKB_PACKET_FLAG_CTR_INIT BIT_5
+
+/* Specify that hash must be appended to output packet */
+#define TKB_PACKET_FLAG_HASHAPPEND BIT_6
+
+/* Specify for AES-XTS (stateful) that the initial IV must be computed from
+   Key2. */
+#define TKB_PACKET_FLAG_XTS_INIT BIT_7
+
+/* Specify for inbound ESP tunnel operations to keep outer tunnel header */
+#define TKB_PACKET_FLAG_KEEP_OUTER BIT_8
+
+/* Specify for outbound ESP IPv6 tunnel operations that we copy the flow label*/
+#define TKB_PACKET_FLAG_COPY_FLOWLABEL BIT_9
+
+/* Specify for outbound ESP transport operations that we always encapsulate the
+   last extension header is it is Destination Options. */
+#define TKB_PACKET_FLAG_ENC_LAST_DEST BIT_10
+
+/* Structure to represent optional per-packet parameters */
+typedef struct
+{
+    uint32_t PacketFlags; /* Per packet flags. Zero if none apply, bitwise
+                              or of TKB_PACKET_FLAG_* constants. */
+    uint32_t BypassByteCount; /* The number of bytes of the packet
+                                that must be bypassed (copied
+                                unmodified) */
+    uint8_t PadByte;   /* A single-byte value that can be specified
+                          per packet.
+                          - Next Header for outbound IPsec.
+                          - Record Type for outbound SSL/TLS
+                          - Number of valid bits in last byte for SNOW/ZUC
+                          - Pad alignment minus 1 for outbound basic
+                            hash-encrypt.
+                          - Record header alignment for inbound DTLS with
+                            header processing.
+                       */
+    uint8_t *IV_p;      /* Only applies when IvSrc is SAB_IV_SRC_TOKEN */
+
+    uint32_t AdditionalValue; /* Required for protocol-specific applications
+                                 - Pad alignment for outbound IPSec/SSL/TLS
+                                 - Rollover counter for outbound SRTP
+                                 - SRTCP index for outbound SRTCP
+                                 - AAD length for basic crypto/hash.
+                                 - Count value for wireless algorithms
+                                 - J value for AES-XTS
+                                 - Packet ID for outbound IPsec IPv4 tunnel
+                                 - Reduced window size for inbound IPsec */
+    uint8_t *AAD_p;     /* Addtional authentication data, for basic crypto and
+                           hash operations and also for combined
+                           crypto-authentication algorithms such as GCM.
+                           If this is NULL, any additional authentication
+                           data is at the start of the packet instead.
+
+                           For inbound SSL/TLS/DTLS: if nonzero, pointer
+                           to the last 32-byte block of the packet.
+                           This can be required if the packet data is not
+                           in a contiguous buffer.
+                         */
+
+    /* The following fields are filled in by the Token Builder (are outputs)
+     */
+
+    uint16_t Prev_NH_Offset; /* Offset where Next Header should be patched */
+    /* As input, if nonzero, specify the number of bytes in the packet that
+       are accessible for header parsing (if the packet is not in a contiguous
+       buffer) */
+    uint16_t TOS_TC_DF;  /* TOS_TC byte (and DF bit at bit 9) in
+                            tunnel header. */
+    uint8_t CLE; /* Classification errors */
+    uint8_t ResultFlags; /* Flags to pass to result token */
+} TokenBuilder_Params_t;
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_GetContextSize
+ *
+ * Determine the size of the token context record in 32-bit words, which may
+ * depend on the SA parameters.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure
+ * TokenContextWord32Count_p (output)
+ *   Required size of the Token Context Record in 32-bit words.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the input data structures are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_GetContextSize(
+    const SABuilder_Params_t * const SAParams_p,
+    unsigned int * const TokenContextWord32Count_p);
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext
+ *
+ * Create a Token Context Record.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_p (output)
+ *   Buffer to hold the Token Context Record. It must point to a valid
+ *   storage buffer that is large enough to hold the Token
+ *   Context. Before calling this function, the application must call
+ *   TokeBuilder_GetContextSize() with the same SA parameters and
+ *   allocate a buffer of that size.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_BuildContext(
+    const SABuilder_Params_t * const SAParams_p,
+    void * const TokenContext_p);
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_Next_PktId
+ *
+ * Increment the PktID if the Token Context describes an IPv4 ESP Tunnel
+ * operation
+ *
+ */
+unsigned int
+TokenBuilder_Next_PktId(
+    const void * const TokenContext_p,
+    unsigned int PktId);
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_GetSize
+ *
+ * Determine the size of a packet token.
+ *
+ * TokenContext_p (input)
+ *   Points to the Token Context Record.
+ * TokenWord32Count_p (output)
+ *   Expected size of the packet token in 32-bit words, depending on the
+ *   contents of the Token Context Record. For some protocols, the
+ *   actual token size depends on the packet contents as well, but in
+ *   this case the maximum token size for that context is returned.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the input data structures are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_GetSize(
+    const void * const TokenContext_p,
+    unsigned int * const TokenWord32Count_p);
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildToken
+ *
+ * Create a packet token, which is required by the packet engine to
+ * process the packet correctly.
+ *
+ * TokenContext_p (input/output)
+ *   Pointer to an initialized token context record, as
+ *   produced by TokenBuilder_BuildContext(). Can be updated by this function.
+ * Packet_p (input)
+ *   Pointer to the packet to be processed.
+ * PacketByteCount (input)
+ *   Size of the packet in bytes (including any  bypass).
+ * TKBParams_p (input, output)
+ *   Additional per-packet parameters of the packet. Not all are defined for
+ *   all protocols.
+ * Token_p (output)
+ *   Buffer to store the token. It must point to a valid storage
+ *   buffer large enough to hold the packet token. Before calling this
+ *   function, the application must call TokenBuilder_GetSize() with the
+ *   same token context and allocate a buffer of that size.
+ * TokenWord32Count_p (output)
+ *   Actual size of the packet token in 32-bit words, which may be less
+ *   than the size returned by TokebBuilder_GetSize().
+ * TokenHeaderWord_p (output)
+ *   Token Header Word. The Reuse Context field (bits 21..20) is always
+ *   set to 1 1 (Force update before reload), which ensures correct
+ *   operation. For performance reasons, the application could modify this
+ *   field as follows, after calling this function and before submitting the
+ *   token to the packet engine:
+ *   - If the token is generated for a packet operation using the same SA
+ *     as the previous operation on the same packet engine, change the field to
+ *     0 1 (clear bit 21).
+ *   - Else change the field to 0 0 (clear both bits 21 and 20).
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the token context are invalid.
+ * TKB_BAD_PACKET if the packet has an invalid header or its size is out of
+ *                range or its size is wrongly aligned for a block cipher.
+ */
+TokenBuilder_Status_t
+TokenBuilder_BuildToken(
+    void * const TokenContext_p,
+    const uint8_t *const Packet_p,
+    const uint32_t PacketByteCount,
+    TokenBuilder_Params_t * const TKBParams_p,
+    void * const Token_p,
+    uint32_t * const TokenWord32Count_p,
+    uint32_t * const TokenHeaderWord_p);
+
+
+#endif /* TOKEN_BUILDER_H_ */
+
+
+/* end of file token_builder.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_internal.h
new file mode 100644
index 0000000..e8e8bf6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_internal.h
@@ -0,0 +1,266 @@
+/* token_builder_interna.h
+ *
+ * Internal APIs for the Token Builder implementation.
+ * This includes thee actual definition of the Token Context Record.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef TOKEN_BUILDER_INTERNAL_H_
+#define TOKEN_BUILDER_INTERNAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "token_builder.h"
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Various fields in the token header word.
+ */
+#define TKB_HEADER_RC_NO_REUSE       0x00000000
+#define TKB_HEADER_RC_REUSE          0x00100000
+#define TKB_HEADER_RC_AUTO_REUSE     0x00200000
+
+#define TKB_HEADER_IP                0x00020000
+
+#ifdef TKB_NO_INPUT_PACKET_POINTER
+#define TKB_HEADER_IP_OPTION TKB_HEADER_IP
+#else
+#define TKB_HEADER_IP_OPTION 0
+#endif
+
+#ifdef TKB_AUTODETECT_CONTEXT_REUSE
+#define TKB_HEADER_RC_OPTION TKB_HEADER_RC_AUTO_REUSE
+#else
+#define TKB_HEADER_RC_OPTION TKB_HEADER_RC_NO_REUSE
+#endif
+
+#define TKB_HEADER_DEFAULT           (TKB_HEADER_RC_OPTION | TKB_HEADER_IP_OPTION)
+
+#define TKB_HEADER_C                 0x02000000
+
+
+#define TKB_HEADER_UPD_HDR           0x00400000
+#define TKB_HEADER_APP_RES           0x00800000
+
+#define TKB_HEADER_PAD_VERIFY        0x01000000
+#define TKB_HEADER_IV_DEFAULT        0x00000000
+#define TKB_HEADER_IV_PRNG           0x04000000
+#define TKB_HEADER_IV_TOKEN_2WORDS   0x18000000
+#define TKB_HEADER_IV_TOKEN_4WORDS   0x1c000000
+
+#define TKB_HEADER_U                 0x20000000
+
+/* CCM flag byte, includes Adata and L=4, M has to be filled in */
+#define TKB_CCM_FLAG_ADATA_L4        0x43
+/* CCM flag byte, includes Adata and L=3, M has to be filled in */
+#define TKB_CCM_FLAG_ADATA_L3        0x42
+
+#define TKB_ESP_FLAG_CLEAR_DF      BIT_0
+#define TKB_ESP_FLAG_SET_DF       BIT_1
+#define TKB_ESP_FLAG_REPLACE_DSCP  BIT_2
+#define TKB_ESP_FLAG_CLEAR_ECN     BIT_3
+#define TKB_ESP_FLAG_NAT           BIT_6
+#define TKB_DTLS_FLAG_PLAINTEXT_HDR BIT_4
+#define TKB_DTLS_FLAG_CAPWAP       BIT_5
+
+/* The protocol values have to agree with those used in token_builder_core.c
+ */
+typedef enum
+{
+    TKB_PROTO_ESP_OUT = 0,
+    TKB_PROTO_ESP_IN = 1,
+    TKB_PROTO_ESP_CCM_OUT = 2,
+    TKB_PROTO_ESP_CCM_IN = 3,
+    TKB_PROTO_ESP_GCM_OUT = 4,
+    TKB_PROTO_ESP_GCM_IN = 5,
+    TKB_PROTO_ESP_GMAC_OUT = 6,
+    TKB_PROTO_ESP_GMAC_IN = 7,
+    TKB_PROTO_SSLTLS_OUT = 8,
+    TKB_PROTO_SSLTLS_IN = 9,
+    TKB_PROTO_BASIC_CRYPTO = 10,
+    TKB_PROTO_BASIC_HASH = 11,
+    TKB_PROTO_SRTP_OUT = 12,
+    TKB_PROTO_SRTP_IN = 13,
+    TKB_PROTO_BASIC_CRYPTHASH = 14,
+    TKB_PROTO_BASIC_CCM_OUT = 15,
+    TKB_PROTO_BASIC_CCM_IN = 16,
+    TKB_PROTO_BASIC_GCM_OUT = 17,
+    TKB_PROTO_BASIC_GCM_IN = 18,
+    TKB_PROTO_BASIC_GMAC_OUT = 19,
+    TKB_PROTO_BASIC_GMAC_IN = 20,
+    TKB_PROTO_SSLTLS_GCM_OUT = 21,
+    TKB_PROTO_SSLTLS_GCM_IN = 22,
+    TKB_PROTO_BASIC_XTS_CRYPTO = 23,
+    TKB_PROTO_BASIC_KASUMI_HASH = 24,
+    TKB_PROTO_BASIC_SNOW_HASH = 25,
+    TKB_PROTO_BASIC_ZUC_HASH = 26,
+    TKB_PROTO_BASIC_HASHENC = 27,
+    TKB_PROTO_BASIC_DECHASH = 28,
+    TKB_PROTO_BASIC_CHACHAPOLY_OUT = 29,
+    TKB_PROTO_BASIC_CHACHAPOLY_IN = 30,
+    TKB_PROTO_TLS13_GCM_OUT = 31,
+    TKB_PROTO_TLS13_GCM_IN = 32,
+    TKB_PROTO_TLS13_CHACHAPOLY_OUT = 33,
+    TKB_PROTO_TLS13_CHACHAPOLY_IN = 34,
+    TKB_PROTO_ESP_CHACHAPOLY_OUT = 35,
+    TKB_PROTO_ESP_CHACHAPOLY_IN = 36,
+    TKB_PROTO_SSLTLS_CHACHAPOLY_OUT = 37,
+    TKB_PROTO_SSLTLS_CHACHAPOLY_IN = 38,
+    TKB_PROTO_SSLTLS_CCM_OUT = 39,
+    TKB_PROTO_SSLTLS_CCM_IN = 40,
+    TKB_PROTO_TLS13_CCM_OUT = 41,
+    TKB_PROTO_TLS13_CCM_IN = 42,
+    TKB_PROTO_BASIC_HMAC_PRECOMPUTE = 43,
+    TKB_PROTO_BASIC_HMAC_CTXPREPARE = 44,
+    TKB_PROTO_BASIC_BYPASS = 45,
+} TokenBuilder_Protocol_t;
+
+/* The header protocol values have to agree with those used in
+ * token_builder_core.c.
+ *
+ * Header protocol operations in the token builder attempt to achieve the
+ * same results as firmware using the extended IPsec operations.
+ *
+ * Values are chosen the same as in sa_builder_extended_internal.h
+ */
+typedef enum
+{
+    TKB_HDR_BYPASS = 0,
+    TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS = 1,
+    TKB_HDR_IPV4_OUT_TUNNEL = 2,
+    TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS = 3,
+    TKB_HDR_IPV4_IN_TUNNEL = 4,
+    TKB_HDR_IPV4_OUT_TRANSP = 5,
+    TKB_HDR_IPV4_IN_TRANSP = 6,
+    TKB_HDR_IPV6_OUT_TUNNEL = 7,
+    TKB_HDR_IPV6_IN_TUNNEL = 8,
+    TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS = 9,
+    TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS = 10,
+    TKB_HDR_IPV6_OUT_TRANSP = 11,
+    TKB_HDR_IPV6_IN_TRANSP = 12,
+
+    /* DTLS and DLTS-CAPWAP */
+    TKB_HDR_IPV4_OUT_DTLS = 13,
+    TKB_HDR_IPV6_OUT_DTLS = 33,
+    TKB_HDR_DTLS_UDP_IN = 14,
+
+    /* IPsec with NAT-T. Must be in the same order as the non NAT-T
+       counterparts */
+    TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT = 21,
+    TKB_HDR_IPV4_OUT_TUNNEL_NATT = 22,
+    TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS_NATT = 23,
+    TKB_HDR_IPV4_IN_TUNNEL_NATT = 24,
+    TKB_HDR_IPV4_OUT_TRANSP_NATT = 25,
+    TKB_HDR_IPV4_IN_TRANSP_NATT = 26,
+    TKB_HDR_IPV6_OUT_TUNNEL_NATT = 27,
+    TKB_HDR_IPV6_IN_TUNNEL_NATT = 28,
+    TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS_NATT = 29,
+    TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS_NATT = 30,
+    TKB_HDR_IPV6_OUT_TRANSP_NATT = 31,
+    TKB_HDR_IPV6_IN_TRANSP_NATT = 32,
+
+} TokenBuilder_HdrProto_t;
+
+/* The IV handling values have to agree with those used in token_builder_core.c
+ */
+typedef enum
+{
+    TKB_IV_INBOUND_CTR = 0,
+    TKB_IV_INBOUND_CBC = 1,
+    TKB_IV_OUTBOUND_CTR = 2,
+    TKB_IV_OUTBOUND_CBC = 3,
+    TKB_IV_COPY_CBC = 4,
+    TKB_IV_COPY_CTR = 5,
+    TKB_IV_OUTBOUND_2WORDS = 6,
+    TKB_IV_OUTBOUND_4WORDS = 7,
+    TKB_IV_OUTBOUND_TOKEN_2WORDS = 8,
+    TKB_IV_COPY_TOKEN_2WORDS = 9,
+    TKB_IV_OUTBOUND_TOKEN_SRTP = 10,
+    TKB_IV_KASUMI_F8 = 11,
+    TKB_IV_SNOW_UEA2 = 12,
+    TKB_IV_ZUC_EEA3 = 13,
+    TKB_IV_OUTBOUND_TOKEN_4WORDS = 14,
+    TKB_IV_COPY_TOKEN_4WORDS = 15,
+} TokenBuilder_IVHandling_t;
+
+
+/* Context update handling for SSL/TLS. The values have to agree with
+   those used in token_builder_core.c
+*/
+typedef enum
+{
+    TKB_UPD_NULL = 0,
+    TKB_UPD_ARC4 = 1,
+    TKB_UPD_IV2 = 2,
+    TKB_UPD_IV4 = 3,
+    TKB_UPD_BLK = 4,
+} TokenBuilder_UpdateHandling_t;
+
+
+/* The TokenBuilder_Context_t (Token Context Record) contains all
+   information that the Token Builder requires for each SA.
+*/
+typedef struct
+{
+    uint32_t TokenHeaderWord;
+    uint8_t protocol;
+    uint8_t hproto;
+    uint8_t IVByteCount;
+    uint8_t ICVByteCount;
+    uint8_t PadBlockByteCount;
+    uint8_t ExtSeq;
+    uint8_t AntiReplay;
+    uint8_t SeqOffset;
+    uint8_t IVOffset;
+    uint8_t DigestWordCount;
+    uint8_t IVHandling;
+    uint8_t DigestOffset;
+    uint8_t protocol_next;
+    uint8_t hproto_next;
+    uint8_t IVHandling_next;
+    uint8_t HeaderWordFields_next;
+    uint32_t NATT_Ports;
+    union {
+        struct {
+            uint8_t UpdateHandling;
+            uint8_t ESPFlags;
+            uint8_t TTL;
+            uint8_t DSCP;
+            uint32_t CCMSalt;
+            uint32_t CW0,CW1; /* Context control words */
+        } generic;
+        struct { // Make the SRTP salt key overlap with fields not used in SRTP.
+            uint32_t SaltKey0,SaltKey1,SaltKey2,SaltKey3;
+        } srtp;
+    } u;
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+    uint8_t TunnelIP[32];
+#endif
+} TokenBuilder_Context_t;
+
+
+#endif /* TOKEN_BUILDER_INTERNAL_H_ */
+
+/* end of file token_builder_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_macros.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_macros.h
new file mode 100644
index 0000000..db0fbab
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/builder/token/token_builder_macros.h
@@ -0,0 +1,1323 @@
+/* token_builder_macros.h
+ *
+ * Macros to be used inside the Token Builder. Main purpose is to evaluate
+ * variables that are used inside generated code.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef TOKEN_BUILDER_MACROS_H_
+#define TOKEN_BUILDER_MACROS_H_
+
+#include "log.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/* Values to be added to Context Control Word 0 for per-packet options */
+#define TKB_PERPKT_HASH_FIRST     0x00000010
+#define TKB_PERPKT_HASH_NO_FINAL  0x00000020
+#define TKB_PERPKT_CTR_INIT       0x00000040
+#define TKB_PERPKT_ARC4_INIT      0x00000080
+#define TKB_PERPKT_XTS_INIT       0x00000080
+
+#define TKB_PERPKT_HASH_STORE     0x00000040
+#define TKB_PERPKT_HASH_CMPRKEY   0x00000080
+
+#define TKB_RESFLAG_INIPV6        BIT_0
+#define TKB_RESFLAG_FROMETHER     BIT_1
+#define TKB_RESFLAG_OUTIPV6       BIT_2
+#define TKB_RESFLAG_INBTUNNEL     BIT_3
+
+#define EVAL_TokenHeaderWord() (EVAL_packetsize() | \
+             TokenContext_Internal_p->TokenHeaderWord | \
+             (EVAL_per_packet_options() != 0?TKB_HEADER_C:0) | \
+             (EVAL_u_word() != 0 ? TKB_HEADER_U:0))
+
+#define EVAL_per_packet_options() PacketOptions(TokenContext_Internal_p,\
+                                                TKBParams_p->PacketFlags, PacketByteCount - TKBParams_p->BypassByteCount)
+
+#define EVAL_u_word() UWord(TokenContext_Internal_p, TKBParams_p)
+
+#define EVAL_appendhash() ((unsigned)((TKBParams_p->PacketFlags &   \
+                                       TKB_PACKET_FLAG_HASHAPPEND) != 0 || \
+                               TokenContext_Internal_p->SeqOffset==0))
+
+/* The following values are each a parameter, either in the Token Context,
+   or in the Packet Parameters or a parameter to the token builder function */
+#define EVAL_cw0() ((unsigned)TokenContext_Internal_p->u.generic.CW0)
+#define EVAL_cw1() ((unsigned)TokenContext_Internal_p->u.generic.CW1)
+#define EVAL_proto() ((unsigned)TokenContext_Internal_p->protocol)
+#define EVAL_hproto() ((unsigned)TokenContext_Internal_p->hproto)
+#define EVAL_ivlen() ((unsigned)TokenContext_Internal_p->IVByteCount)
+#define EVAL_icvlen() ((unsigned)TokenContext_Internal_p->ICVByteCount)
+#define EVAL_hstatelen() ((unsigned)TokenContext_Internal_p->DigestWordCount)
+#define EVAL_hstatelen_bytes() ((unsigned)TokenContext_Internal_p->DigestWordCount*4)
+#define EVAL_cipher_is_aes() ((unsigned)(TokenContext_Internal_p->PadBlockByteCount==16))
+#define EVAL_pad_blocksize()                               \
+    PadBlockSize(TokenContext_Internal_p->PadBlockByteCount, 0)
+#define EVAL_pad_blocksize_out()                               \
+    PadBlockSize(TokenContext_Internal_p->PadBlockByteCount,  \
+                 TokenContext_Internal_p->hproto==0?TKBParams_p->AdditionalValue:0)
+#define EVAL_seq_offset() ((unsigned)TokenContext_Internal_p->SeqOffset)
+#define EVAL_iv_offset() ((unsigned)TokenContext_Internal_p->IVOffset)
+#define EVAL_digest_offset() ((unsigned)TokenContext_Internal_p->DigestOffset)
+#define EVAL_capwap_out() ((TokenContext_Internal_p->u.generic.ESPFlags & TKB_DTLS_FLAG_CAPWAP)?4:0)
+#define EVAL_capwap_in() ((TokenContext_Internal_p->u.generic.ESPFlags & TKB_DTLS_FLAG_CAPWAP) && IsCAPWAP(Packet_p+bypass+hdrlen)?4:0)
+#define EVAL_packetsize() ((unsigned)PacketByteCount)
+#define EVAL_aadlen_pkt() (EVAL_aad()==NULL?(unsigned)TKBParams_p->AdditionalValue:0)
+#define EVAL_aadlen_tkn() (EVAL_aad()==NULL?0:(unsigned)TKBParams_p->AdditionalValue)
+#define EVAL_aadlen_out() (EVAL_extseq()==0?0:(unsigned)TKBParams_p->AdditionalValue)
+#define EVAL_swap_j() ByteSwap32(TKBParams_p->AdditionalValue)
+#define EVAL_paylen_ccm() (EVAL_packetsize()-EVAL_bypass() - \
+                                        EVAL_ivlen()-EVAL_aadlen_pkt()- \
+                   (EVAL_proto()==TKB_PROTO_BASIC_CCM_IN || \
+                    EVAL_proto()==TKB_PROTO_BASIC_CHACHAPOLY_IN?EVAL_icvlen():0))
+#define EVAL_basic_swaplen() ByteSwap32(EVAL_paylen_ccm())
+#define EVAL_aadlen_swap() ByteSwap16(TKBParams_p->AdditionalValue)
+#define EVAL_aadlen_swap32() ByteSwap32(TKBParams_p->AdditionalValue)
+#define EVAL_aadpad() (PaddedSize(TKBParams_p->AdditionalValue + 18 ,16) - \
+                       TKBParams_p->AdditionalValue - 18)
+#define EVAL_aadpadpoly() (PaddedSize(TKBParams_p->AdditionalValue, 16) -  \
+                           TKBParams_p->AdditionalValue)
+#define EVAL_basic_hashpad() (PaddedSize( EVAL_paylen_ccm(), 16) - EVAL_paylen_ccm())
+
+#define EVAL_bypass() ((unsigned)TKBParams_p->BypassByteCount)
+#define EVAL_ivhandling() ((unsigned)TokenContext_Internal_p->IVHandling)
+#define EVAL_upd_handling() ((unsigned)TokenContext_Internal_p->u.generic.UpdateHandling)
+#define EVAL_extseq() ((unsigned)TokenContext_Internal_p->ExtSeq)
+#define EVAL_antireplay() ((unsigned)TokenContext_Internal_p->AntiReplay)
+#define EVAL_salt() ((unsigned)TokenContext_Internal_p->u.generic.CCMSalt)
+#define EVAL_basic_salt() (EVAL_salt() - (TKBParams_p->AdditionalValue==0?0x40:0))
+#define EVAL_swaplen() (EVAL_proto()==TKB_PROTO_SSLTLS_OUT||    \
+                        EVAL_proto()==TKB_PROTO_SSLTLS_IN||     \
+                        EVAL_proto()==TKB_PROTO_SSLTLS_GCM_OUT||\
+                        EVAL_proto()==TKB_PROTO_SSLTLS_GCM_IN||  \
+                        EVAL_proto()==TKB_PROTO_SSLTLS_CCM_OUT||\
+                        EVAL_proto()==TKB_PROTO_SSLTLS_CCM_IN||  \
+                        EVAL_proto()==TKB_PROTO_SSLTLS_CHACHAPOLY_OUT||\
+                        EVAL_proto()==TKB_PROTO_SSLTLS_CHACHAPOLY_IN?  \
+                         ByteSwap16(EVAL_paylen()):             \
+                         ByteSwap32(EVAL_paylen()))
+#define EVAL_swap_fraglen() ByteSwap16(EVAL_packetsize() - EVAL_bypass() + \
+       EVAL_ivlen() + EVAL_icvlen() - hdrlen + \
+           (unsigned int)(EVAL_upd_handling() >= TKB_UPD_IV2) * \
+                                       EVAL_pad_bytes())
+#define EVAL_swap_fraglen_tls13() ByteSwap16(EVAL_packetsize() - EVAL_bypass() + \
+                                             EVAL_icvlen() + 1 + EVAL_count())
+#define EVAL_hashpad() (PaddedSize( EVAL_paylen(), 16) - EVAL_paylen())
+
+#define EVAL_paylen() PayloadSize(TokenContext_Internal_p, \
+                                  EVAL_packetsize() - EVAL_bypass() - hdrlen, \
+                                  TKBParams_p->AdditionalValue)
+#define EVAL_iv() TKBParams_p->IV_p
+#define EVAL_aad() TKBParams_p->AAD_p
+
+#define EVAL_paylen_tls13_ccm_out() (EVAL_packetsize() - EVAL_bypass() + \
+                                     1 + EVAL_count())
+#define EVAL_paylen_tls13_ccm_in() (EVAL_packetsize() - EVAL_bypass() - \
+                                    EVAL_icvlen() - 5)
+#define EVAL_swaplen3() ByteSwap24(EVAL_paylen())
+#define EVAL_swaplen3_tls13_out() ByteSwap24(EVAL_paylen_tls13_ccm_out())
+#define EVAL_swaplen3_tls13_in() ByteSwap24(EVAL_paylen_tls13_ccm_in())
+#define EVAL_hashpad_tls13_out() (PaddedSize( EVAL_paylen_tls13_ccm_out(), 16) - EVAL_paylen_tls13_ccm_out())
+#define EVAL_hashpad_tls13_in() (PaddedSize( EVAL_paylen_tls13_ccm_in(), 16) - EVAL_paylen_tls13_ccm_in())
+
+
+/* EVAL_pad_remainder() is used to check whether the packet payload
+   on inbound packets is a multiple of the pad block size. If not,
+   the packet is invalid and shall not be processed.
+ */
+#define EVAL_pad_remainder() PadRemainder(EVAL_packetsize() - 8 - \
+                                           EVAL_ivlen() - EVAL_icvlen() - \
+                                           EVAL_bypass() - hdrlen,     \
+                                           EVAL_pad_blocksize())
+
+/* EVAL_pad_bytes() is used to compute the number of bytes that must
+   be added to outbound packets.
+
+   For IPsec, two bytes (next header and the number of padded bytes)
+   must be added in any case. It is the difference between the padded
+   payload size and the unpadded payload size.
+
+   For SSL and TLS, one byte (number of padded bytes) must be added in
+   any case.  Padding has to be applied to the payload plus MAC.
+*/
+#define EVAL_pad_bytes() ComputePadBytes(TokenContext_Internal_p,\
+                            EVAL_packetsize()-EVAL_bypass()-hdrlen,     \
+                            EVAL_pad_blocksize_out())
+#define EVAL_pad_bytes_basic() (PaddedSize(EVAL_packetsize() - EVAL_bypass() -EVAL_antireplay() - EVAL_aadlen_pkt(), \
+                  TokenContext_Internal_p->PadBlockByteCount) -  \
+                                EVAL_packetsize()+EVAL_bypass()+EVAL_antireplay()+EVAL_aadlen_pkt())
+#define EVAL_pad_bytes_hashenc() ComputePadBytes(TokenContext_Internal_p, \
+            EVAL_packetsize() - EVAL_bypass() + \
+             TokenContext_Internal_p->PadBlockByteCount - EVAL_aadlen_pkt(), \
+            PadBlockSize(TokenContext_Internal_p->PadBlockByteCount,TKBParams_p->PadByte + 1))
+
+
+#define EVAL_srtp_iv0() (TokenContext_Internal_p->u.srtp.SaltKey0)
+#define EVAL_srtp_iv1() SRTP_IV1(TokenContext_Internal_p,\
+                                 Packet_p + EVAL_bypass())
+#define EVAL_srtp_iv2() SRTP_IV2(TokenContext_Internal_p, \
+                                 Packet_p + EVAL_bypass(), \
+                                 PacketByteCount - EVAL_bypass(), \
+                                 TKBParams_p->AdditionalValue)
+#define EVAL_srtp_iv3() SRTP_IV3(TokenContext_Internal_p, \
+                                 Packet_p + EVAL_bypass(), \
+                                 PacketByteCount - EVAL_bypass(), \
+                                 TKBParams_p->AdditionalValue)
+#define EVAL_srtp_offset() SRTP_Offset(TokenContext_Internal_p, \
+                                       Packet_p + EVAL_bypass(),  \
+                                       PacketByteCount - EVAL_bypass(), \
+                                       TKBParams_p->AdditionalValue)
+#define EVAL_srtp_swaproc() ByteSwap32(TKBParams_p->AdditionalValue)
+
+
+#define EVAL_ssltls_lastblock() (Packet_p + EVAL_packetsize() - 16 - 16*EVAL_cipher_is_aes())
+
+#define EVAL_ssltls_lastword() (Packet_p + EVAL_packetsize() - 4)
+
+#define EVAL_count() TKBParams_p->AdditionalValue
+#define EVAL_bearer_dir_fresh() TokenContext_Internal_p->u.generic.CCMSalt
+
+#if TKB_HAVE_PROTO_IPSEC==1|TKB_HAVE_PROTO_SSLTLS==1
+/*----------------------------------------------------------------------------
+ * PadRemainder
+ *
+ * Compute the remainder of ByteCount when devided by BlockByteCount..
+ * BlockByteCount must be a power of 2.
+ */
+static unsigned int
+PadRemainder(unsigned int ByteCount,
+             unsigned int BlockByteCount)
+{
+    unsigned int val;
+    val = ByteCount & (BlockByteCount - 1);
+    LOG_INFO("TokenBuilder_BuildToken: Input message %u pad align=%u "
+             "remainder=%u\n",
+             ByteCount, BlockByteCount,val);
+    return val;
+}
+#endif
+
+#if TKB_HAVE_PROTO_IPSEC==1||TKB_HAVE_PROTO_SSLTLS==1||TKB_HAVE_PROTO_BASIC==1
+/*----------------------------------------------------------------------------
+ * PaddedSize
+ *
+ * Compute the size of a packet of length ByteCount when padded to a multiple
+ * of BlockByteCount.
+ *
+ * BlockByteCount must be a power of 2.
+ */
+static unsigned int
+PaddedSize(unsigned int ByteCount,
+           unsigned int BlockByteCount)
+{
+    return (ByteCount + BlockByteCount - 1) & ~(BlockByteCount - 1);
+}
+#endif
+
+#if TKB_HAVE_PROTO_IPSEC==1||TKB_HAVE_PROTO_SSLTLS==1||TKB_HAVE_PROTO_BASIC==1
+/*----------------------------------------------------------------------------
+ * PadBlockSize
+ *
+ * Select the pad block size: select the override value if it is appropriate,
+ * else select the default value.
+ *
+ * The override value is appropriate if it is a power of two and if it is
+ * greater than the default value and at most 256.
+ */
+static unsigned int
+PadBlockSize(unsigned int DefaultVal,
+             unsigned int OverrideVal)
+{
+    if (OverrideVal > DefaultVal  &&
+        OverrideVal <= 256 &&
+        (OverrideVal  & (OverrideVal - 1)) == 0) // Check power of two.
+    {
+        LOG_INFO("TokenBuilder_Buildtoken: Override pad alignment from %u to %u\n",
+                 DefaultVal, OverrideVal);
+        return OverrideVal;
+    }
+    else
+    {
+        return DefaultVal;
+    }
+}
+#endif
+
+#if TKB_HAVE_PROTO_SSLTLS==1
+/*----------------------------------------------------------------------------
+ * IsCAPWAP
+ *
+ * Check if there is a CAPWAP header at the given location in the packet.
+ */
+static inline bool
+IsCAPWAP(const uint8_t * const Packet_p)
+{
+    return Packet_p[0]==1;
+}
+
+#endif
+/*----------------------------------------------------------------------------
+ * ByteSwap32
+ *
+ * Return a 32-bit value byte-swapped.
+ */
+static inline unsigned int
+ByteSwap32(unsigned int val)
+{
+    return ((val << 24) & 0xff000000) |
+           ((val << 8)  & 0x00ff0000) |
+           ((val >> 8)  & 0x0000ff00) |
+           ((val >> 24) & 0x000000ff);
+}
+
+#if TKB_HAVE_PROTO_IPSEC==1||TKB_HAVE_PROTO_SSLTLS==1||TKB_HAVE_PROTO_BASIC==1
+/*----------------------------------------------------------------------------
+ * ByteSwap16
+ *
+ * Return a 16-bit value byte-swapped.
+ */
+static inline unsigned int
+ByteSwap16(unsigned int val)
+{
+    return ((val << 8) & 0xff00) |
+           ((val >> 8) & 0x00ff);
+}
+
+
+/*----------------------------------------------------------------------------
+ * ByteSwap24
+ *
+ * Return a 24-bit value byte-swapped.
+ */
+static inline unsigned int
+ByteSwap24(unsigned int val)
+{
+    return ((val << 16) & 0x00ff0000) |
+           ( val        & 0x0000ff00) |
+           ((val >> 16) & 0x000000ff);
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * PacketOptions
+ *
+ * Return the per-packet options depending on the packet flags and the protocol.
+ * In this implementaiton only the TKB_PACKET_FLAG_ARC4_INIT flag is
+ * honored for the ARC4 SSL/TLS case.
+ */
+static inline unsigned int
+PacketOptions(const TokenBuilder_Context_t * TokenContext_p,
+              unsigned int flags, unsigned int PacketByteCount)
+{
+    unsigned int val = 0;
+    unsigned int protocol = TokenContext_p->protocol;
+
+    if ((protocol == TKB_PROTO_SSLTLS_OUT || protocol == TKB_PROTO_SSLTLS_IN ||
+            protocol == TKB_PROTO_BASIC_CRYPTO) &&
+        (flags & TKB_PACKET_FLAG_ARC4_INIT) != 0)
+        val |= TKB_PERPKT_ARC4_INIT;
+
+    if (protocol == TKB_PROTO_BASIC_XTS_CRYPTO &&
+        (flags & TKB_PACKET_FLAG_XTS_INIT) != 0)
+        val |= TKB_PERPKT_XTS_INIT;
+
+    if (protocol == TKB_PROTO_BASIC_HASH &&
+        ((TokenContext_p->SeqOffset != 0 &&
+         TokenContext_p->DigestWordCount >= 16) ||
+         (TokenContext_p->u.generic.CW0 & 0x07800000) == 0x07800000))
+    {
+        if ((flags & TKB_PACKET_FLAG_HASHFIRST) != 0)
+            val |= TKB_PERPKT_HASH_FIRST;
+        if ((flags & TKB_PACKET_FLAG_HASHFINAL) == 0)
+            val |= TKB_PERPKT_HASH_NO_FINAL;
+    }
+
+    if (protocol == TKB_PROTO_BASIC_HMAC_PRECOMPUTE ||
+        protocol == TKB_PROTO_BASIC_HMAC_CTXPREPARE)
+    {
+        unsigned int KeyLimit = 64;
+        if (TokenContext_p->DigestWordCount==16)
+            KeyLimit = 128;
+
+        val |= TKB_PERPKT_HASH_FIRST;
+        if (PacketByteCount > KeyLimit)
+            val |= TKB_PERPKT_HASH_CMPRKEY;
+
+        if (protocol == TKB_PROTO_BASIC_HMAC_CTXPREPARE)
+            val |= TKB_PERPKT_HASH_STORE;
+    }
+
+    if (val != 0)
+    {
+        LOG_INFO("TokenBuilder_BuildToken: non-zero per-packet options: %x\n",
+                 val);
+    }
+
+    return val;
+}
+
+/*----------------------------------------------------------------------------
+ * UWord
+ *
+ * Return the U-word that is optionally present in the Token. It can be used
+ * to specify non-byte aligned packet sizes in SNOW and ZUC authentication
+ * algorithms or to specify the per-packet window size for inbound IPSsec ESP.
+ */
+static inline unsigned int
+UWord(const TokenBuilder_Context_t * TokenContext_p,
+      const TokenBuilder_Params_t *TKBParams_p)
+{
+    switch (TokenContext_p->protocol)
+    {
+    case TKB_PROTO_ESP_IN:
+    case TKB_PROTO_ESP_CCM_IN:
+    case TKB_PROTO_ESP_GCM_IN:
+    case TKB_PROTO_ESP_GMAC_IN:
+    case TKB_PROTO_ESP_CHACHAPOLY_IN:
+        if (TokenContext_p->AntiReplay < 32)
+            return 0;
+        switch(TKBParams_p->AdditionalValue)
+        {
+        case 64:
+            return 0x00200000;
+        case 128:
+            return 0x00400000;
+        case 256:
+            return 0x00600000;
+        case 512:
+            return 0x00800000;
+        default:
+            return 0;
+        }
+    case TKB_PROTO_BASIC_SNOW_HASH:
+    case TKB_PROTO_BASIC_ZUC_HASH:
+        return TKBParams_p->PadByte;
+    default:
+        return 0;
+    }
+}
+
+
+#if TKB_HAVE_PROTO_IPSEC==1||TKB_HAVE_PROTO_SSLTLS==1|TKB_HAVE_PROTO_BASIC==1
+/*----------------------------------------------------------------------------
+ * ComputePadBytes
+ *
+ * TokenContext_p (input)
+ *     Token context.
+ * PayloadByteCount (input)
+ *    Size of message to be padded in bytes.
+ * PadBlockByteCount (input)
+ *    Block size to which the payload must be padded.
+ */
+static unsigned int
+ComputePadBytes(const TokenBuilder_Context_t *TokenContext_p,
+                unsigned int PayloadByteCount,
+                unsigned int PadBlockByteCount)
+{
+    unsigned int PadByteCount;
+    if(TokenContext_p->protocol == TKB_PROTO_SSLTLS_OUT ||
+        TokenContext_p->protocol == TKB_PROTO_BASIC_HASHENC)
+    {
+        PadByteCount = PaddedSize(PayloadByteCount + 1 +
+                                  TokenContext_p->IVByteCount +
+                                  TokenContext_p->ICVByteCount,
+                                  PadBlockByteCount) -
+          PayloadByteCount - TokenContext_p->ICVByteCount -
+          TokenContext_p->IVByteCount;
+        LOG_INFO("TokenBuilder_BuildToken: SSL/TLS padding message %u\n"
+                 "  with mac %u pad bytes=%u align=%u\n",
+                 PayloadByteCount,
+                 TokenContext_p->ICVByteCount,
+                 PadByteCount, PadBlockByteCount);
+    }
+    else
+    {
+        PadByteCount =  PaddedSize(PayloadByteCount + 2, PadBlockByteCount) -
+            PayloadByteCount;
+        LOG_INFO("TokenBuilder_BuildToken: IPsec padding message %u "
+                 "pad bytes=%u align=%u\n",
+                 PayloadByteCount, PadByteCount, PadBlockByteCount);
+    }
+    return PadByteCount;
+}
+#endif
+
+#if TKB_HAVE_PROTO_IPSEC==1||TKB_HAVE_PROTO_SSLTLS==1
+/*----------------------------------------------------------------------------
+ * PayloadSize
+ *
+ * TokenContext_p (input)
+ *     Token context.
+ * MessageByteCount (input)
+ *     Size of the input packet, excluding bypass.
+ * AdditionalValue
+ *     Additional value supplied in pacekt parameters. This may be a pad
+ *     block size or the number of pad bytes.
+ *
+ * Compute the payload length in bytes for all SSL/TLS and for ESP with AES-CCM.
+ * This is not used for other ESP modes.
+ */
+static unsigned int
+PayloadSize(const TokenBuilder_Context_t *TokenContext_p,
+            unsigned int MessageByteCount,
+            unsigned int AdditionalValue)
+{
+    int size;
+    switch(TokenContext_p->protocol)
+    {
+    case TKB_PROTO_ESP_CCM_OUT:
+        /* Need paddded payload size, pad message */
+        return PaddedSize(MessageByteCount + 2,
+           PadBlockSize(TokenContext_p->PadBlockByteCount, AdditionalValue));
+    case TKB_PROTO_ESP_CCM_IN:
+        /* Need paddded payload size, derive from message length, subtract
+           headers and trailers.*/
+        return MessageByteCount - TokenContext_p->IVByteCount -
+            TokenContext_p->ICVByteCount - 8;
+    case TKB_PROTO_SSLTLS_OUT:
+    case TKB_PROTO_SSLTLS_GCM_OUT:
+    case TKB_PROTO_SSLTLS_CCM_OUT:
+    case TKB_PROTO_SSLTLS_CHACHAPOLY_OUT:
+        /* Need fragment length */
+        return MessageByteCount;
+    case TKB_PROTO_SSLTLS_IN:
+    case TKB_PROTO_SSLTLS_GCM_IN:
+    case TKB_PROTO_SSLTLS_CCM_IN:
+    case TKB_PROTO_SSLTLS_CHACHAPOLY_IN:
+        /* Need fragment length. Must remove any headers, padding and trailers
+         */
+        size = (int)MessageByteCount;
+        if ((TokenContext_p->u.generic.ESPFlags & TKB_DTLS_FLAG_CAPWAP) != 0)
+            size -= 4;
+        // Deduce CAPWAP/DTLS header.
+        size -= TokenContext_p->ICVByteCount;
+        size -= TokenContext_p->IVByteCount;
+        if (TokenContext_p->ExtSeq != 0)
+            size -= 8; /* Deduce epoch and sequence number for DTLS */
+        size -= 5;   /* Deduce type, version and fragment length. */
+        if (size < 0)
+            return 0xffffffffu;
+        if(TokenContext_p->u.generic.UpdateHandling != TKB_UPD_NULL &&
+           TokenContext_p->u.generic.UpdateHandling != TKB_UPD_ARC4)
+        {
+            if (PadRemainder((unsigned int)size + TokenContext_p->ICVByteCount,
+                             TokenContext_p->PadBlockByteCount) != 0)
+                /* Padded payload + ICV must be a multiple of block size */
+                return 0xffffffffu;
+/* Report negative payload size due to subtraction of pad bytes as 0
+ * rather than 0xffffffff, so the the operation will still be
+ * execcuted. This to avoid timing attacks. See RFC5246, section
+ * 6.2.3.2. */
+        }
+        return (unsigned int)size;
+    default:
+        LOG_CRIT("Token Builder: PayloadSize used with unsupported protocol\n");
+        return 0;
+    }
+}
+#endif
+
+/* SRTP_IV1
+
+   Form second word of IV.  (Exclusive or of salt key and SSRC).
+*/
+static unsigned int
+SRTP_IV1(
+        const TokenBuilder_Context_t *TokenContext_p,
+        const uint8_t *Packet_p)
+{
+    unsigned int SSRCOffset;
+    if (TokenContext_p->ExtSeq != 0)
+    { // SRTCP
+        SSRCOffset = 4;
+    }
+    else
+    { // SRTP
+        SSRCOffset = 8;
+    }
+
+    if (Packet_p == NULL)
+        return 0;
+
+    return TokenContext_p->u.srtp.SaltKey1 ^ ((Packet_p[SSRCOffset]) |
+                                              (Packet_p[SSRCOffset+1]<<8) |
+                                              (Packet_p[SSRCOffset+2]<<16) |
+                                              (Packet_p[SSRCOffset+3]<<24));
+}
+
+/* SRTP_IV2
+
+   Form third word of IV (SRTCP: exclusive or with MSB of SRTCP index.
+   SRTP: Exclusive or with ROC).
+*/
+static unsigned int
+SRTP_IV2(
+        const TokenBuilder_Context_t *TokenContext_p,
+        const uint8_t *Packet_p,
+        unsigned int MessageByteCount,
+        unsigned int AdditionalValue)
+{
+    unsigned int ByteOffset;
+
+    if (Packet_p == NULL)
+        return 0;
+
+    if (TokenContext_p->ExtSeq != 0)
+    { // SRTCP
+        uint32_t SRTCP_Index;
+        if (TokenContext_p->protocol == TKB_PROTO_SRTP_OUT)
+        {   // For outbound packet, SRTCP index is supplied parameter.
+            SRTCP_Index = AdditionalValue & 0x7fffffff;
+        }
+        else
+        {   // For inbound, extract it from the packet.
+            ByteOffset = MessageByteCount - 4 - TokenContext_p->AntiReplay -
+                TokenContext_p->ICVByteCount;
+            SRTCP_Index = ((Packet_p[ByteOffset]&0x7f)<<24) |
+                (Packet_p[ByteOffset+1]<<16) ;
+        }
+        return TokenContext_p->u.srtp.SaltKey2 ^ ByteSwap32(SRTCP_Index>>16);
+    }
+    else
+    { // SRTP
+        return TokenContext_p->u.srtp.SaltKey2 ^ ByteSwap32(AdditionalValue);
+    }
+}
+
+
+
+/* SRTP_IV3
+
+   Form fourth word of IV (SRTCP: exclusive or with LSB of SRTCP index.
+   SRTP: Exclusive or with seq no in packet).
+*/
+static unsigned int
+SRTP_IV3(
+        const TokenBuilder_Context_t *TokenContext_p,
+        const uint8_t *Packet_p,
+        unsigned int MessageByteCount,
+        unsigned int AdditionalValue)
+{
+    unsigned int ByteOffset;
+
+    if (Packet_p == NULL)
+        return 0;
+
+    if (TokenContext_p->ExtSeq != 0)
+    { // SRTCP
+        uint32_t SRTCP_Index;
+        if (TokenContext_p->protocol == TKB_PROTO_SRTP_OUT)
+        {   // For outbound packet, SRTCP index is supplied parameter.
+            SRTCP_Index = AdditionalValue;
+        }
+        else
+        {   // For inbound, extract it from the packet.
+            ByteOffset = MessageByteCount - 4 - TokenContext_p->AntiReplay -
+                TokenContext_p->ICVByteCount;
+            SRTCP_Index = (Packet_p[ByteOffset+2]<<8) |
+                (Packet_p[ByteOffset+3]) ;
+        }
+        return TokenContext_p->u.srtp.SaltKey3 ^ ByteSwap32(SRTCP_Index<<16);
+    }
+    else
+    {
+        return TokenContext_p->u.srtp.SaltKey3 ^ (Packet_p[2] |
+                                                  (Packet_p[3]<<8));
+    }
+}
+
+#if TKB_HAVE_PROTO_SRTP==1
+/* SRTP_Offset
+
+   Compute the crypto offset (in bytes) of an SRTP packet.
+
+   If no crypto used: return 0.
+   If packet is invalid: return offset larger than message size.
+*/
+static unsigned int
+SRTP_Offset(
+        const TokenBuilder_Context_t *TokenContext_p,
+        const uint8_t *Packet_p,
+        unsigned int MessageByteCount,
+        unsigned int AdditionalValue)
+{
+    unsigned int ByteOffset;
+    if (TokenContext_p->IVByteCount == 0)
+        return 0;
+
+    if (Packet_p == NULL)
+        return 0;
+
+    if (TokenContext_p->ExtSeq != 0)
+    { // SRTCP
+        uint32_t SRTCP_Index;
+        if (TokenContext_p->protocol == TKB_PROTO_SRTP_OUT)
+        {   // For outbound packet, SRTCP index is supplied parameter.
+            SRTCP_Index = AdditionalValue;
+        }
+        else
+        {   // For inbound, extract it from the packet.
+            ByteOffset = MessageByteCount - 4 - TokenContext_p->AntiReplay -
+                TokenContext_p->ICVByteCount;
+            if (ByteOffset > MessageByteCount)
+            {
+                LOG_INFO("TokenBuilder_BuildToken: Short packet\n");
+                return MessageByteCount + 1;
+
+            }
+            SRTCP_Index = Packet_p[ByteOffset]<<24; // Only get MSB.
+        }
+        if ((SRTCP_Index & BIT_31) != 0) // Test the E bit.
+            return 8; // SRTCP always has crypto offset 8.
+        else
+            return 0; // Return 0 if no encryption is used.
+    }
+    else
+    { // SRTP
+        unsigned int NCSRC = Packet_p[0] & 0xf; // Number of CSRC fields.
+        ByteOffset = 12 + 4*NCSRC;
+        if ( (Packet_p[0] & BIT_4) != 0) // Extension header present.
+        {
+            if (ByteOffset + 4 > MessageByteCount)
+            {
+                LOG_INFO("TokenBuilder_BuildToken: Short packet\n");
+                return MessageByteCount + 1;
+            }
+            ByteOffset += 4 + 4*(Packet_p[ByteOffset+2]<<8) +
+                4*Packet_p[ByteOffset+3]; // Add length field from extension.
+        }
+        return ByteOffset;
+    }
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------------
+ * TokenBuilder_CopyBytes
+ *
+ * Copy a number of bytes from src to dst. src is a byte pointer, which is
+ * not necessarily byte aligned. Always write a whole number of words,
+ * filling the last word with null-bytes if necessary.
+ */
+static void
+TokenBuilder_CopyBytes(uint32_t *dest,
+                       const uint8_t *src,
+                       unsigned int ByteCount)
+{
+    unsigned int i,j;
+    uint32_t w;
+    if (src == NULL)
+    {
+        LOG_CRIT("TokenBuilder trying copy data from NULL pointer\n");
+        return;
+    }
+    for (i=0; i<ByteCount/sizeof(uint32_t); i++)
+    {
+        w=0;
+        for (j=0; j<sizeof(uint32_t); j++)
+        {
+            w = (w>>8) | (*src++ << 24);
+        }
+        *dest++ = w;
+    }
+    if (ByteCount % sizeof(uint32_t) != 0)
+    {
+        w=0;
+        for (j=0; j<ByteCount % sizeof(uint32_t); j++)
+        {
+            w = w | (*src++ << (8*j));
+        }
+        *dest++ = w;
+    }
+}
+
+#if TKB_HAVE_EXTENDED_IPSEC==1 || TKB_HAVE_EXTENDED_DTLS==1
+
+
+/*-----------------------------------------------------------------------------
+ * TokenBuilder_ParseIPHeader
+ *
+ * Parse ths IP header and provide values for the following variables
+ * - hdrlen (returned). Number of bytes to skip in input packet before
+ *                      inserting/removing ESP header.
+ * - ohdrlen            Number of bytes in output packet before
+ *                      ESP header or decrypted payload.
+ * - outlen             Length of output IP packet (outbound only).
+ * - nh                 Next header byte in IPv6 header (if applicable)
+ *                      For tunnel outbound modes (IPv4 or IPv6), it is the
+ *                      DSCP+ECN byte instead.
+ * - nextheader         Next header byte to insert in ESP trailer.
+ * - prev_nhoffset      Offset in packet where next header byte is replaced.
+ *                      For IPv6 tunnel mode, it is the flow label instead.
+ * - ecn_fixup_instr    ECN fixup instruction for inbound tunnel mode.
+ */
+static inline uint32_t
+TokenBuilder_ParseIPHeader(
+        const uint8_t *Packet_p,
+        const unsigned int PacketByteCount,
+        const TokenBuilder_Context_t *TokenContext_Internal_p,
+        TokenBuilder_Params_t * TKBParams_p,
+        uint32_t *ohdrlen_p,
+        uint32_t *outlen_p,
+        uint32_t *nh_p,
+        uint32_t *nextheader_p,
+        uint32_t *prev_nhoffset_p,
+        uint32_t *ecn_fixup_instr_p)
+{
+    uint32_t nh = 0;
+    uint32_t ohdrlen = 0;
+    uint32_t outlen = 0;
+    uint8_t nextheader = TKBParams_p->PadByte;
+    uint32_t prev_nhoffset = 0;
+    uint32_t hdrlen = 0;
+    uint32_t ecn_fixup_instr = 0x20000000;
+    uint8_t hproto=TokenContext_Internal_p->hproto;
+    bool fIPv6;
+    uint32_t MaxHdrLen = TKBParams_p->Prev_NH_Offset;
+
+    TKBParams_p->CLE = 0;
+    TKBParams_p->Prev_NH_Offset = 0;
+    TKBParams_p->TOS_TC_DF = 0;
+    TKBParams_p->ResultFlags = 0;
+
+    if (hproto)
+    {
+        /* Check whether the packet is IPv6. For outbound tunnel modes
+           this is the only form of header parsing done. For non-protocol
+           modes, do not look at the header at all
+
+           Also collect the TOS bytes (DSCP+ECN) and the IPv6 flow label.*/
+        if (PacketByteCount < 20)
+        {
+            TKBParams_p->CLE = 3;
+            return 0xffffffff;
+        }
+        fIPv6 = (Packet_p[0] & 0xf0) == 0x60;
+        TKBParams_p->ResultFlags |= fIPv6;
+        if ((fIPv6 && PacketByteCount < 40) ||
+            (!fIPv6 && (Packet_p[0] & 0xf0) != 0x40))
+        {
+            TKBParams_p->CLE = 3;
+            return 0xffffffff;
+        }
+        if (!fIPv6)
+        {
+            nh = Packet_p[1]; /* DSCP+ECN byte */
+            TKBParams_p->TOS_TC_DF = nh | ((Packet_p[6]&0x40)?0x100:0);
+        }
+        else
+        {
+            uint32_t w = (Packet_p[0]<<24) | (Packet_p[1]<<16) |
+                (Packet_p[2]<<8) |  Packet_p[3];
+            nh = (w>>20) & 0xff; /* DSCP+ECN byte */
+            TKBParams_p->TOS_TC_DF = nh;
+            if (TKBParams_p->PacketFlags & TKB_PACKET_FLAG_COPY_FLOWLABEL)
+                prev_nhoffset = w & 0xfffff; /* Flow label */
+        }
+    }
+
+    switch (hproto)
+    {
+    case 0:
+        break;
+    case TKB_HDR_IPV4_OUT_TUNNEL:
+        ohdrlen = 20;
+        nextheader = fIPv6 ? 41 : 4;
+        break;
+    case TKB_HDR_IPV6_OUT_TUNNEL:
+        ohdrlen = 40;
+        nextheader = fIPv6 ? 41 : 4;
+        break;
+    case TKB_HDR_IPV4_OUT_TUNNEL_NATT:
+        ohdrlen = 28;
+        nextheader = fIPv6 ? 41 : 4;
+        nh = Packet_p[1]; /* DSCP+ECN byte */
+        break;
+    case TKB_HDR_IPV6_OUT_TUNNEL_NATT:
+        ohdrlen = 48;
+        nextheader = fIPv6 ? 41 : 4;
+        break;
+    default:
+        /* Parse the IP header, sufficiently to find the location of the
+           ESP header or where it should be inserted. */
+        if (fIPv6)
+        {
+            int ChainState = 0;
+            // 0 no specifics encountered.
+            // 1 routing header encountered, immediately exit when
+            //   destination opts header found (before parsing that header).
+
+            if (MaxHdrLen == 0 || MaxHdrLen > PacketByteCount)
+            {
+                MaxHdrLen = PacketByteCount;
+            }
+            nh = Packet_p[6];
+            prev_nhoffset = 6;
+            hdrlen = 40;
+            nextheader = nh;
+            while (nextheader == 0 || nextheader == 43 ||
+                   nextheader == 44 || nextheader == 60)
+            {
+                if (MaxHdrLen < hdrlen + 8) {
+                    TKBParams_p->CLE = 3;
+                    return 0xffffffff;
+                }
+                /* Assume we want to encapsulate any destination options
+                   after the routine header */
+                if (nextheader == 43 &&
+                    (hproto == TKB_HDR_IPV6_OUT_TRANSP ||
+                     hproto == TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS ||
+                     hproto == TKB_HDR_IPV6_OUT_TRANSP_NATT ||
+                     hproto == TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS_NATT))
+                {
+                    ChainState=1;
+                }
+                /* Fragment header encountered, these packets cannot be
+                   processed.*/
+                if (nextheader == 44)
+                {
+                    TKBParams_p->CLE = 1;
+                    return 0xffffffff;
+                }
+                nextheader = Packet_p[hdrlen];
+                prev_nhoffset = hdrlen;
+                hdrlen += Packet_p[hdrlen+1] * 8 + 8;
+                if ((nextheader == 60 && ChainState == 1) ||
+                    ChainState == 2)
+                {
+                    break;
+                }
+            }
+        }
+        else
+        {
+            hdrlen = (Packet_p[0] & 0xf) * 4;
+            nextheader = Packet_p[9];
+            /* Special protocol 254 for Firmware tests, encode the
+               desired nextheader byte in PktId field */
+            if (nextheader == 254)
+                nextheader = Packet_p[5];
+            /* Check for fragment, reject fragments  */
+            if ((Packet_p[6] & ~0xc0) != 0 || Packet_p[7] != 0)
+            {
+                    TKBParams_p->CLE = 1;
+                    return 0xffffffff;
+            }
+        }
+
+        switch (hproto)
+        {
+        case TKB_HDR_IPV4_OUT_TRANSP:
+        case TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS:
+            if (fIPv6)
+            {
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            ohdrlen = hdrlen;
+            break;
+        case TKB_HDR_IPV6_OUT_TRANSP:
+        case TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS:
+            if (!fIPv6)
+            {
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            ohdrlen = hdrlen;
+            break;
+        case TKB_HDR_IPV4_IN_TRANSP:
+        case TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS:
+            if (nextheader != 50 || fIPv6)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            ohdrlen = hdrlen;
+            break;
+        case TKB_HDR_IPV6_IN_TRANSP:
+        case TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS:
+            if (nextheader != 50 || !fIPv6)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            TKBParams_p->Prev_NH_Offset = prev_nhoffset +
+                TKBParams_p->BypassByteCount ;
+            ohdrlen = hdrlen;
+            break;
+        case TKB_HDR_IPV4_OUT_TRANSP_NATT:
+        case TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT:
+            if (fIPv6)
+            {
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            ohdrlen = hdrlen + 8;
+            break;
+        case TKB_HDR_IPV6_OUT_TRANSP_NATT:
+        case TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS_NATT:
+            if (!fIPv6)
+            {
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            ohdrlen = hdrlen + 8;
+            break;
+        case TKB_HDR_IPV4_IN_TRANSP_NATT:
+        case TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS_NATT:
+            if (nextheader != 17 || fIPv6)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            ohdrlen = hdrlen;
+            hdrlen += 8;
+            break;
+        case TKB_HDR_IPV6_IN_TRANSP_NATT:
+        case TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS_NATT:
+            if (nextheader != 17 || !fIPv6)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            TKBParams_p->Prev_NH_Offset = prev_nhoffset  +
+                TKBParams_p->BypassByteCount;
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            ohdrlen = hdrlen;
+            hdrlen += 8;
+            break;
+        case TKB_HDR_IPV4_IN_TUNNEL:
+        case TKB_HDR_IPV6_IN_TUNNEL:
+            if (nextheader != 50)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            if ((TKBParams_p->PacketFlags & TKB_PACKET_FLAG_KEEP_OUTER) != 0)
+                ohdrlen = hdrlen;
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_INBTUNNEL;
+            ecn_fixup_instr = 0xa6000000 +
+                ((TKBParams_p->TOS_TC_DF & 0x3)<<19)  +
+                ohdrlen + TKBParams_p->BypassByteCount;
+            break;
+        case TKB_HDR_IPV4_IN_TUNNEL_NATT:
+        case TKB_HDR_IPV6_IN_TUNNEL_NATT:
+            if (nextheader != 17)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            if ((TKBParams_p->PacketFlags & TKB_PACKET_FLAG_KEEP_OUTER) != 0)
+                ohdrlen = hdrlen;
+            hdrlen += 8;
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_INBTUNNEL;
+            ecn_fixup_instr = 0xa6000000 +
+                ((TKBParams_p->TOS_TC_DF & 0x3)<<19)  +
+                ohdrlen + TKBParams_p->BypassByteCount;
+            break;
+        case TKB_HDR_IPV4_OUT_DTLS:
+        case TKB_HDR_IPV6_OUT_DTLS:
+            hdrlen += 8;
+            ohdrlen = hdrlen;
+            /* Must be UDP or UDPlite */
+            if (nextheader != 17 && nextheader != 136)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            nh = nextheader;
+            prev_nhoffset = Packet_p[6];
+            nextheader = TKBParams_p->PadByte;
+            if (fIPv6) TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            break;
+        case TKB_HDR_DTLS_UDP_IN:
+            hdrlen += 8;
+            ohdrlen = hdrlen;
+            /* Must be UDP or UDPlite */
+            if (nextheader != 17 && nextheader != 136)
+            {
+
+                TKBParams_p->CLE = 3;
+                return 0xffffffff;
+            }
+            if ((TokenContext_Internal_p->u.generic.ESPFlags &
+                 TKB_DTLS_FLAG_PLAINTEXT_HDR) != 0)
+            {
+                ohdrlen += 5;
+                if (TKBParams_p->PadByte >= 8)
+                {
+                    ohdrlen += (TKBParams_p->PadByte - 5);
+                }
+            }
+            if (fIPv6) TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            break;
+        case TKB_HDR_IPV6_OUT_TUNNEL:
+        case TKB_HDR_IPV6_OUT_TUNNEL_NATT:
+            TKBParams_p->ResultFlags |= TKB_RESFLAG_OUTIPV6;
+            break;
+        }
+    }
+
+    if (hproto == TKB_HDR_IPV4_OUT_TRANSP ||
+        hproto == TKB_HDR_IPV6_OUT_TRANSP ||
+        hproto == TKB_HDR_IPV4_OUT_TRANSP_NATT ||
+        hproto == TKB_HDR_IPV6_OUT_TRANSP_NATT ||
+        hproto == TKB_HDR_IPV4_OUT_TUNNEL ||
+        hproto == TKB_HDR_IPV6_OUT_TUNNEL ||
+        hproto == TKB_HDR_IPV4_OUT_TUNNEL_NATT ||
+        hproto == TKB_HDR_IPV6_OUT_TUNNEL_NATT)
+    {
+        outlen = ohdrlen + 8 +
+            TokenContext_Internal_p->IVByteCount +
+            TokenContext_Internal_p->ICVByteCount +
+            PaddedSize(PacketByteCount - hdrlen + 2,
+                       TokenContext_Internal_p->PadBlockByteCount);
+    }
+    else if (hproto == TKB_HDR_IPV4_OUT_DTLS ||
+             hproto == TKB_HDR_IPV6_OUT_DTLS)
+    {
+        if (TokenContext_Internal_p->protocol == TKB_PROTO_SSLTLS_OUT &&
+            TokenContext_Internal_p->IVByteCount > 0)
+            outlen = 13 + TokenContext_Internal_p->IVByteCount +
+                PaddedSize(PacketByteCount - hdrlen + 1 + TokenContext_Internal_p->ICVByteCount,
+                           TokenContext_Internal_p->PadBlockByteCount);
+        else
+            outlen = PacketByteCount - hdrlen + 13 + TokenContext_Internal_p->IVByteCount +
+                TokenContext_Internal_p->ICVByteCount;
+        if ((TokenContext_Internal_p->u.generic.ESPFlags & TKB_DTLS_FLAG_CAPWAP) != 0)
+            outlen += 4;
+    }
+
+    *nh_p = nh;
+    *ohdrlen_p = ohdrlen;
+    *outlen_p = outlen;
+    *nextheader_p = nextheader;
+    *prev_nhoffset_p = prev_nhoffset;
+    *ecn_fixup_instr_p = ecn_fixup_instr;
+    return hdrlen;
+}
+
+/*-----------------------------------------------------------------------------
+ * FormDSCP_ECN
+ *
+ * Form the DSCP/ECN byte in the tunnel header. Use the value provided in the
+ * input packet, but optionally replace the DSCP field or clear the ECN field.
+ */
+static uint8_t
+FormDSCP_ECN(
+        const TokenBuilder_Context_t *TokenContext_Internal_p,
+        const uint8_t DSCP_ECN_in)
+{
+    uint8_t DSCP_ECN_out = DSCP_ECN_in;
+    if (TokenContext_Internal_p->u.generic.ESPFlags & TKB_ESP_FLAG_REPLACE_DSCP)
+    {
+        DSCP_ECN_out = (DSCP_ECN_out & 0x3) | \
+            ((TokenContext_Internal_p->u.generic.DSCP)<<2);
+    }
+    if (TokenContext_Internal_p->u.generic.ESPFlags & TKB_ESP_FLAG_CLEAR_ECN)
+    {
+        DSCP_ECN_out &= 0xfc;
+    }
+    return DSCP_ECN_out;
+}
+
+/*-----------------------------------------------------------------------------
+ * Form_W0_IP4
+ *
+ * Form the first word of the IPv4 tunnel header.
+ */
+static uint32_t
+Form_W0_IP4(
+    const TokenBuilder_Context_t *TokenContext_Internal_p,
+    const uint16_t PktLen,
+    const uint8_t DSCP_ECN_in)
+{
+    return 0x45 |
+        (FormDSCP_ECN(TokenContext_Internal_p, DSCP_ECN_in) << 8) |
+        (ByteSwap16(PktLen) << 16);
+}
+
+/*-----------------------------------------------------------------------------
+ * Form_W1_IP4
+ *
+ * Form the second word of the IPv4 tunnel header. Contains DF bit.
+ */
+static uint32_t
+Form_W1_IP4(
+        const TokenBuilder_Context_t *TokenContext_Internal_p,
+        const uint8_t FlagByte,
+        const uint32_t PktId)
+{
+    bool DF = (FlagByte & 0x40) != 0;
+    if (TokenContext_Internal_p->u.generic.ESPFlags & TKB_ESP_FLAG_SET_DF)
+        DF=true;
+    else if (TokenContext_Internal_p->u.generic.ESPFlags & TKB_ESP_FLAG_CLEAR_DF)
+        DF=false;
+    return (DF ? 0x00400000 : 0x00000000) |
+        ((PktId >> 8) & 0xff) | ((PktId & 0xff) << 8);
+}
+
+/*-----------------------------------------------------------------------------
+ * Form_W2_IP4
+ *
+ * Form the third word of the IPv4 tunnel header. Contains header checksum,
+ * which is computed over all other fields of the header.
+ */
+static uint32_t
+Form_W2_IP4(
+    const TokenBuilder_Context_t *TokenContext_Internal_p,
+    const uint32_t w0,
+    const uint32_t w1)
+{
+    uint32_t w2;
+    uint32_t sum;
+    unsigned int i;
+    w2 = TokenContext_Internal_p->u.generic.TTL |
+        (TokenContext_Internal_p->hproto==TKB_HDR_IPV4_OUT_TUNNEL_NATT ?
+         0x1100 : 0x3200);
+    sum = (w0 >> 16)+(w0 & 0xffff) +
+        (w1 >> 16)+(w1 & 0xffff) + w2;
+    for (i=0; i<4; i++)
+    {
+        sum = sum + TokenContext_Internal_p->TunnelIP[2*i] +
+            256 * TokenContext_Internal_p->TunnelIP[2*i + 1];
+    }
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum = (sum >> 16) + (sum & 0xffff);
+    return (sum ^ 0xffff) << 16 | w2;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Form_W0_IP6
+ *
+ * Form the first word of the IPv6 tunnel header.
+ */
+static uint32_t
+Form_W0_IP6(
+    const TokenBuilder_Context_t *TokenContext_Internal_p,
+    const uint8_t DSCP_ECN_in,
+    const uint32_t FlowLabel)
+{
+    return ByteSwap32(0x60000000 |
+            (FormDSCP_ECN(TokenContext_Internal_p,DSCP_ECN_in) << 20) |
+             FlowLabel);
+}
+
+/*-----------------------------------------------------------------------------
+ * Form_W1_IP6
+ *
+ * Form the second word of the IPv6 tunnel header.
+ */
+static uint32_t
+Form_W1_IP6(
+    const TokenBuilder_Context_t *TokenContext_Internal_p,
+    const uint16_t PktLen)
+{
+    return ByteSwap16(PktLen - 40) |
+        (TokenContext_Internal_p->u.generic.TTL << 24) |
+        (TokenContext_Internal_p->hproto==TKB_HDR_IPV6_OUT_TUNNEL_NATT ?
+         0x110000 : 0x320000);
+}
+
+
+#define EVAL_prev_nhoffset() prev_nhoffset
+#define EVAL_hdrlen() TokenBuilder_ParseIPHeader(Packet_p + bypass, \
+                                                 PacketByteCount - bypass, \
+                                                 TokenContext_Internal_p, \
+                                                 TKBParams_p, \
+                                                 &ohdrlen, \
+                                                 &outlen, \
+                                                 &nh, \
+                                                 &nextheader, \
+                                                 &prev_nhoffset, \
+                                                 &ecn_fixup_instr)
+#define EVAL_ohdrlen() ohdrlen
+#define EVAL_outlen() outlen
+#define EVAL_nh() nh
+#define EVAL_ecn_fixup_instr() ecn_fixup_instr
+#define EVAL_outer_ecn()  (TKBParams_p->TOS_TC_DF & 0x3)
+#define EVAL_tunnel_w0_ip4() Form_W0_IP4(TokenContext_Internal_p, \
+                                         outlen, nh)
+#define EVAL_tunnel_w1_ip4() Form_W1_IP4(TokenContext_Internal_p, \
+                                         nextheader==4?Packet_p[bypass+6]:0, \
+                                         TKBParams_p->AdditionalValue)
+#define EVAL_tunnel_w2_ip4() Form_W2_IP4(TokenContext_Internal_p, \
+                                         tunnel_w0_ip4, tunnel_w1_ip4)
+#define EVAL_tunnel_w0_ip6() Form_W0_IP6(TokenContext_Internal_p, nh,\
+                                         prev_nhoffset)
+#define EVAL_tunnel_w1_ip6() Form_W1_IP6(TokenContext_Internal_p, outlen)
+
+#define EVAL_ports_natt() TokenContext_Internal_p->NATT_Ports
+#define EVAL_nextheader() nextheader
+#define EVAL_tunnel_ip_addr() TokenContext_Internal_p->TunnelIP
+#define EVAL_dst_ip_addr() (TokenContext_Internal_p->TunnelIP + 4)
+#define EVAL_is_nat() ((TokenContext_Internal_p->u.generic.ESPFlags & TKB_ESP_FLAG_NAT) != 0)
+#else
+#define EVAL_hdrlen() 0
+#define EVAL_ohdrlen() 0
+#define EVAL_nextheader() ((unsigned)TKBParams_p->PadByte)
+#define EVAL_ecn_fixup_instr() 0x20000000
+#endif
+
+/*-----------------------------------------------------------------------------
+ * Switch_Proto
+ *
+ * Switch the Token Context back from HMAC precompute to the original
+ * protocol.
+ *
+ * Return true if protocol was switched.
+ */
+static inline bool
+Switch_Proto(TokenBuilder_Context_t *ctx)
+{
+    if(ctx->protocol == TKB_PROTO_BASIC_HMAC_CTXPREPARE)
+    {
+        ctx->protocol = ctx->protocol_next;
+        ctx->hproto = ctx->hproto_next;
+        ctx->IVHandling = ctx->IVHandling_next;
+        ctx->TokenHeaderWord |= ctx->HeaderWordFields_next << 22;
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+#endif /* TOKEN_BUILDER_MACROS_H_ */
+
+/* end of file token_builder_macros.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip201.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip201.h
new file mode 100644
index 0000000..b71f9c8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip201.h
@@ -0,0 +1,86 @@
+/* c_eip201.h
+ *
+ * Configuration options for the EIP201 Driver Library module.
+ * The project-specific cs_eip201.h file is included,
+ * whereafter defaults are provided for missing parameters.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------
+ * Defines that can be used in the cs_xxx.h file
+ */
+
+/* EIP201_STRICT_ARGS
+ *
+ * Set this option to enable checking of all arguments to all EIP201 DL
+ * functions. Disable it to reduce code size and reduce overhead.
+ */
+
+/* EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS <NOI>
+ *
+ * This configures the maximum Number Of Interrupt (NOI) sources
+ * actually available in the EIP201 AIC.
+ * This can be used for strict argument checking.
+ */
+
+/*----------------------------------------------------------------
+ * inclusion of cs_eip201.h
+ */
+
+// EIP-201 Driver Library API
+#include "cs_eip201.h"
+
+
+/*----------------------------------------------------------------
+ * provide backup values for all missing configuration parameters
+ */
+#if !defined(EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS) \
+             || (EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS > 32)
+#undef  EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS
+#define EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS 32
+#endif
+
+
+/*----------------------------------------------------------------
+ * other configuration parameters that cannot be set in cs_xxx.h
+ * but are considered product-configurable anyway
+ */
+
+
+/*----------------------------------------------------------------
+ * correct implementation-specific collisions
+ */
+
+#ifndef EIP201_REMOVE_INITIALIZE
+// EIP201_Initialize internally depends on EIP201_Config_Change
+#ifdef EIP201_REMOVE_CONFIG_CHANGE
+#undef EIP201_REMOVE_CONFIG_CHANGE
+#endif
+#endif
+
+#ifndef EIP201_LO_REG_BASE
+#define EIP201_LO_REG_BASE 0x00
+#endif
+#ifndef EIP201_HI_REG_BASE
+#define EIP201_HI_REG_BASE 0x00
+#endif
+
+
+
+/* end of file c_eip201.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_global.h
new file mode 100644
index 0000000..9afb1d7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_global.h
@@ -0,0 +1,50 @@
+/* c_eip202_global.h
+ *
+ * Default EIP-202 Driver Library Global Control configuration
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP202_GLOBAL_H_
+#define C_EIP202_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip202_global.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+#endif /* C_EIP202_GLOBAL_H_ */
+
+
+/* end of file c_eip202_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_ring.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_ring.h
new file mode 100644
index 0000000..66724fd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip202_ring.h
@@ -0,0 +1,175 @@
+/* c_eip202_ring.h
+ *
+ * Default configuration of the EIP-202 Ring Control Driver Library
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP202_RING_H_
+#define C_EIP202_RING_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Top-level configuration, can override default configuration
+// parameters specified in this file
+#include "cs_eip202_ring.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+//#define EIP202_RING_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+//#define EIP202_RING_DEBUG_FSM
+
+// Set to 1 to enable RDR interrupt generation per packet
+// instead of interrupt generation per result descriptor
+#ifndef EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG
+#define EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG  1
+#endif
+
+// Enables the 64-bit DMA addresses support in the device
+//#define EIP202_64BIT_DEVICE
+
+// Enable anti DMA race condition CDS mechanism.
+// When enabled the Application ID field in the descriptors cannot be used
+// by the Ring Control Driver Library users.
+//#define EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+
+// Disable clustered write operations, e.g. every write operation to
+// an EIP-202 RD register will be followed by one read operation to
+// a pre-defined EIP-202 register
+//#define EIP202_CLUSTERED_WRITES_DISABLE
+
+// CDR Read cache type control (rd_cache field in HIA_CDR_y_DMA_CFG register)
+#ifndef EIP202_RING_CD_RD_CACHE_CTRL
+#define EIP202_RING_CD_RD_CACHE_CTRL            0
+#endif
+
+// CDR Write cache type control (wr_cache field in HIA_CDR_y_DMA_CFG register)
+#ifndef EIP202_RING_CD_WR_CACHE_CTRL
+#define EIP202_RING_CD_WR_CACHE_CTRL            0
+#endif
+
+// RDR Read cache type control (rd_cache field in HIA_RDR_y_DMA_CFG register)
+#ifndef EIP202_RING_RD_RD_CACHE_CTRL
+#define EIP202_RING_RD_RD_CACHE_CTRL            0
+#endif
+
+// RDR Write cache type control (wr_cache field in HIA_RDR_y_DMA_CFG register)
+#ifndef EIP202_RING_RD_WR_CACHE_CTRL
+#define EIP202_RING_RD_WR_CACHE_CTRL            0
+#endif
+
+// AXI bus specific protection configuration: command descriptor data
+#ifndef EIP202_RING_CD_PROT_VALUE
+#define EIP202_RING_CD_PROT_VALUE               0
+#endif
+
+// AXI bus specific protection configuration: result descriptor data
+#ifndef EIP202_RING_RD_PROT_VALUE
+#define EIP202_RING_RD_PROT_VALUE               0
+#endif
+
+// AXI bus specific protection configuration: packet data
+#ifndef EIP202_RING_DATA_PROT_VALUE
+#define EIP202_RING_DATA_PROT_VALUE             0
+#endif
+
+// AXI bus specific protection configuration: token data
+#ifndef EIP202_RING_ACD_PROT_VALUE
+#define EIP202_RING_ACD_PROT_VALUE              0
+#endif
+
+// Enables padding the result descriptor to its full programmed
+// offset with 0xAAAAAAAA, which is the ownership word magic
+// number, to avoid having to do a separate ownership word write. This
+// opposed to just writing the actual result descriptor data. This may be
+// useful in certain systems where partial cache line writes cause read-
+// modify-write operations and therefore filling the whole cacheline may be
+// beneficial even if that means writing out more data than necessary.
+//     0 - disabled
+//     1 - enabled
+// Note: when enabled EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG must be defined too
+#ifndef EIP202_RDR_PAD_TO_OFFSET
+#define EIP202_RDR_PAD_TO_OFFSET                0
+#endif
+
+// When defined the command descriptor write optimization will be applied,
+// e.g. only required words will be written
+//#define EIP202_CDR_OPT1 /* skip writing unused length word */
+//#define EIP202_CDR_OPT2 /* skip writing token buffer address */
+//#define EIP202_CDR_OPT3 /* skip writing SA buffer address */
+
+// When defined the RDR ownership word support will be enabled
+//#define EIP202_RDR_OWNERSHIP_WORD_ENABLE
+
+#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE) && \
+    defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
+#error "Error: EIP202_RDR_OWNERSHIP_WORD_ENABLE excludes \
+           EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS"
+#endif
+
+// Bufferability control for result token DMA writes. Driven on cache type
+// bus bit [0] to Host Interface for all result token DMA writes to control
+// write bufferability:
+// 0b = do not buffer, 1b = allow buffering
+#ifndef EIP202_RING_RD_RES_BUF
+#define EIP202_RING_RD_RES_BUF                  0
+#endif
+
+// Bufferability control for descriptor control word DMA writes. Driven on
+// cache type bus bit [0] to Host Interface for all descriptor control word
+// DMA writes to control write bufferability:
+// 0b = do not buffer, 1b = allow buffering.
+#ifndef EIP202_RING_RD_CTRL_BUF
+#define EIP202_RING_RD_CTRL_BUF                 0
+#endif
+
+// Bufferability control for ownership word DMA writes. Driven on cache
+// type bus bit [0] to Host Interface for all ownership word DMA writes to
+// control write bufferability:
+// 0b = do not buffer, 1b = allow buffering.
+#ifndef EIP202_RING_RD_OWN_BUF
+#define EIP202_RING_RD_OWN_BUF                  1
+#endif
+
+
+#endif /* C_EIP202_RING_H_ */
+
+
+/* end of file c_eip202_ring.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip206.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip206.h
new file mode 100644
index 0000000..bcf1152
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip206.h
@@ -0,0 +1,64 @@
+/* c_eip206.h
+ *
+ * Default configuration EIP-206 Driver Library
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP206_H_
+#define C_EIP206_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip206.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Processing Packet Engine n (n - number of the PE)
+// Input Side
+//#define EIP206_IN_DBUF_BASE           0xA0000
+//#define EIP206_IN_TBUF_BASE           0xA0100
+
+// Output Side
+//#define EIP206_OUT_DBUF_BASE          0xA1C00
+//#define EIP206_OUT_TBUF_BASE          0xA1D00
+
+// PE Options and Version
+//#define EIP206_ARC4_BASE              0xA1FEC
+//#define EIP206_VER_BASE               0xA1FF8
+
+
+#endif /* C_EIP206_H_ */
+
+
+/* end of file c_eip206.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_flow.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_flow.h
new file mode 100644
index 0000000..8f359c9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_flow.h
@@ -0,0 +1,136 @@
+/* c_eip207_flow.h
+ *
+ * Default configuration parameters
+ * for the EIP-207 Flow Control Driver Library
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP207_FLOW_H_
+#define C_EIP207_FLOW_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip207_flow.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum number of EIP-207c Classification Engines that can be used
+// Should not exceed the number of engines physically available
+#ifndef EIP207_FLOW_MAX_NOF_CE_TO_USE
+#define EIP207_FLOW_MAX_NOF_CE_TO_USE                   1
+#endif
+
+// Maximum supported number of flow hash tables
+#ifndef EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE     1
+#endif
+
+// Define this parameter for additional consistency checks in the flow
+// control functionality
+//#define EIP207_FLOW_CONSISTENCY_CHECK
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+//#define EIP207_FLOW_STRICT_ARGS
+
+// Disable clustered write operations, e.g. every write operation to
+// an EIP-207 register will be followed by one read operation to
+// a pre-defined EIP-207 register
+//#define EIP207_FLOW_CLUSTERED_WRITES_DISABLE
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) Record Cache type:
+// If defined then use the  Hihg-Performance (HP) Record Cache,
+// otherwise use the standard Record Cache
+//#define EIP207_FLUE_RC_HP
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) register bank size
+#ifndef EIP207_FLUE_FHT_REG_MAP_SIZE
+#define EIP207_FLUE_FHT_REG_MAP_SIZE                     8192
+#endif
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) CACHEBASE registers
+#ifndef EIP207_FLUE_FHT1_REG_BASE
+#define EIP207_FLUE_FHT1_REG_BASE                        0x00000
+#endif // EIP207_FLUE_FHT1_REG_BASE
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) HASHBASE registers
+#ifndef EIP207_FLUE_FHT2_REG_BASE
+#define EIP207_FLUE_FHT2_REG_BASE                        0x00000
+#endif // EIP207_FLUE_FHT2_REG_BASE
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) SIZE register
+#ifndef EIP207_FLUE_FHT3_REG_BASE
+#define EIP207_FLUE_FHT3_REG_BASE                        0x00000
+#endif // EIP207_FLUE_FHT3_REG_BASE
+
+// EIP-207s Classification Support, options and version registers
+#ifndef EIP207_FLUE_OPTVER_REG_BASE
+#define EIP207_FLUE_OPTVER_REG_BASE                      0x00000
+#endif // EIP207_FLUE_OPTVER_REG_BASE
+
+// EIP-207s Classification Support, Flow Hash Engine (FHASH) registers
+#ifndef EIP207_FLUE_HASH_REG_BASE
+#define EIP207_FLUE_HASH_REG_BASE                        0x00000
+#endif // EIP207_FLUE_HASH_REG_BASE
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+//#define EIP207_FLOW_DEBUG_FSM
+
+// Enable 64-bit DMA address support in the device
+//#define EIP207_64BIT_DEVICE
+
+// Define to disable the large transform record support
+//#define EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+
+// Define to disable type bits in pointers inside flow record.
+//#define EIP207_FLOW_NO_TYPE_BITS_IN_FLOW_RECORD
+
+
+// Flow or transform record (FLUE_STD), Hash bucket (FLUE_DTL)
+// remove wait loop count
+#ifndef EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT
+#define EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT            1000000
+#endif
+
+
+#endif /* C_EIP207_FLOW_H_ */
+
+
+/* end of file c_eip207_flow.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_global.h
new file mode 100644
index 0000000..c9fe63d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip207_global.h
@@ -0,0 +1,213 @@
+/* c_eip207_global.h
+ *
+ * Default configuration parameters
+ * for the EIP-207 Global Control Driver Library
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP207_GLOBAL_H_
+#define C_EIP207_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip207_global.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-207 supported HW version
+#define EIP207_GLOBAL_MAJOR_VERSION                 1
+#define EIP207_GLOBAL_MINOR_VERSION                 0
+#define EIP207_GLOBAL_PATCH_LEVEL                   0
+
+// Maximum number of Classification Engine (EIP-207c) instances
+//#define EIP207_GLOBAL_MAX_NOF_CE_TO_USE           1
+
+// Number of sets of the FRC/TRC/ARC4C HW interfaces (p+1)
+// Maximum number of cache interfaces that can be used
+// Should not exceed the number of cache sets physically available
+#ifndef EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE
+#define EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE     1
+#endif // EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE
+
+// Enable Context Data Endianness Conversion by the Processing Engine hardware
+// Swap bytes within each 32 bit word
+//#define EIP207_GLOBAL_BYTE_SWAP_FLOW_DATA
+
+// Enable Transform Data Endianness Conversion by the Processing Engine hardware
+// Swap bytes within each 32 bit word
+//#define EIP207_GLOBAL_BYTE_SWAP_TRANSFORM_DATA
+
+// Enable ARC4 Context Data Endianness Conversion by the PE hardware
+// Swap bytes within each 32 bit word
+//#define EIP207_GLOBAL_BYTE_SWAP_ARC4_DATA
+
+// Define to disable the FRC
+//#define EIP207_GLOBAL_FRC_DISABLE
+
+// Size of the Flow Record Cache (data RAM) in 32-bit words
+#ifndef EIP207_FRC_RAM_WORD_COUNT
+#define EIP207_FRC_RAM_WORD_COUNT                   512
+#endif // EIP207_FRC_RAM_WORD_COUNT
+
+// Size of the Flow Record Cache (administration RAM) in 32-bit words
+//#define EIP207_FRC_ADMIN_RAM_WORD_COUNT             8192
+
+// Size of the Transform Record Cache (data RAM) in 32-bit words
+#ifndef EIP207_TRC_RAM_WORD_COUNT
+#define EIP207_TRC_RAM_WORD_COUNT                   1024
+#endif // EIP207_TRC_RAM_WORD_COUNT
+
+// Size of the Transform Record Cache (administration RAM) in 32-bit words
+//#define EIP207_TRC_ADMIN_RAM_WORD_COUNT             8192
+
+// Size of the ARC4 Record Cache (data RAM) in 32-bit words
+// Note: ARC4RC is combined with TRC
+#ifndef EIP207_ARC4RC_RAM_WORD_COUNT
+#define EIP207_ARC4RC_RAM_WORD_COUNT                EIP207_TRC_RAM_WORD_COUNT
+#endif // EIP207_ARC4RC_RAM_WORD_COUNT
+
+// Size of the ARC4 Record Cache (administration RAM) in 32-bit words
+//#define EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT          8192
+
+//#define EIP207_FLUE_HAVE_VIRTUALIZATION
+
+// Number of interfaces for virtualization.
+#ifndef EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE
+#define EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE 15
+#endif
+
+// Main hash table size in entries (one entry is one 32-bit word)
+// Table size = 2^(EIP207_FLUEC_TABLE_SIZE+3)
+#ifndef EIP207_FLUEC_TABLE_SIZE
+#define EIP207_FLUEC_TABLE_SIZE                     0
+#endif // EIP207_FLUEC_TABLE_SIZE
+
+// Group size in entries (one entry is one 32-bit word)
+// Group size = 2^EIP207_FLUEC_GROUP_SIZE
+#ifndef EIP207_FLUEC_GROUP_SIZE
+#define EIP207_FLUEC_GROUP_SIZE                     1
+#endif // EIP207_FLUEC_GROUP_SIZE
+
+// Size of the FLUE Cache in 32-bit words
+// FLUEC RAM = Table size * (Group size * 6 + 1)
+#ifndef EIP207_FLUEC_RAM_WORD_COUNT
+#define EIP207_FLUEC_RAM_WORD_COUNT                 128
+#endif // EIP207_FLUEC_RAM_WORD_COUNT
+
+// Input Pull-Up Engine Program RAM size (in 32-bit words), 8KB
+#ifndef EIP207_IPUE_PROG_RAM_WORD_COUNT
+#define EIP207_IPUE_PROG_RAM_WORD_COUNT             2048
+#endif // EIP207_IPUE_PROG_RAM_WORD_COUNT
+
+// Input Flow Post-Processor Engine Program RAM size (in 32-bit words), 8KB
+#ifndef EIP207_IFPP_PROG_RAM_WORD_COUNT
+#define EIP207_IFPP_PROG_RAM_WORD_COUNT             2048
+#endif // EIP207_IFPP_PROG_RAM_WORD_COUNT
+
+// ICE Scratchpad RAM size in 128-byte blocks (1KB)
+#ifndef EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT
+#define EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT     8
+#endif // EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT
+
+// Output Pull-Up Engine Program RAM size (in 32-bit words), 8KB
+#ifndef EIP207_OPUE_PROG_RAM_WORD_COUNT
+#define EIP207_OPUE_PROG_RAM_WORD_COUNT             2048
+#endif // EIP207_OPUE_PROG_RAM_WORD_COUNT
+
+// Output Flow Post-Processor Engine Program RAM size (in 32-bit words), 8KB
+#ifndef EIP207_OFPP_PROG_RAM_WORD_COUNT
+#define EIP207_OFPP_PROG_RAM_WORD_COUNT             2048
+#endif // EIP207_OFPP_PROG_RAM_WORD_COUNT
+
+// OCE Scratchpad RAM size in 128-byte blocks (1KB)
+#ifndef EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT
+#define EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT     8
+#endif // EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT
+
+// Classification engine timer overflow bit
+#ifndef EIP207_ICE_SCRATCH_TIMER_OFLO_BIT
+#define EIP207_ICE_SCRATCH_TIMER_OFLO_BIT           31
+#endif // EIP207_ICE_SCRATCH_TIMER_OFLO_BIT
+
+// Classification engine timer overflow bit
+#ifndef EIP207_OCE_SCRATCH_TIMER_OFLO_BIT
+#define EIP207_OCE_SCRATCH_TIMER_OFLO_BIT           31
+#endif // EIP207_OCE_SCRATCH_TIMER_OFLO_BIT
+
+// Enable firmware version check after the download
+//#define EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+
+#ifdef EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+#ifndef EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS
+#define EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS   100
+#endif // EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS
+#endif // EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+
+// Disable clustered write operations, e.g. every write operation to
+// an EIP-207 register will be followed by one read operation to
+// a pre-defined EIP-207 register
+//#define EIP207_CLUSTERED_WRITES_DISABLE
+
+// Maximum number of read attempts for a 64-bit counter
+#ifndef EIP207_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS
+#define EIP207_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS    2
+#endif
+
+// Maximum number of hash tables supported by the EIP-207 FLUE
+// if the CS_OPTIONS reads 0 for the number of lookup tables
+#ifndef EIP207_GLOBAL_MAX_HW_NOF_FLOW_HASH_TABLES
+#define EIP207_GLOBAL_MAX_HW_NOF_FLOW_HASH_TABLES   17
+#endif
+
+// Flow LookUp Engine (FLUE) lookup mode
+// 0 - legacy single-entry mode
+// 1 - 3-entry bucket-based mode
+#ifndef EIP207_GLOBAL_FLUE_LOOKUP_MODE
+// Default is legacy lookup mode
+#define EIP207_GLOBAL_FLUE_LOOKUP_MODE                     0
+#endif
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+//#define EIP207_GLOBAL_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+//#define EIP207_GLOBAL_DEBUG_FSM
+
+
+#endif /* C_EIP207_GLOBAL_H_ */
+
+
+/* end of file c_eip207_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip74.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip74.h
new file mode 100644
index 0000000..86fd370
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip74.h
@@ -0,0 +1,43 @@
+/* c_eip74.h
+ *
+ * Default configuration parameters for the EIP74 Driver Library.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_EIP74_H_
+#define C_EIP74_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip74.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+// strict argument checking enabled.
+//EIP74_STRICT_ARGS
+
+#endif /* C_EIP74_H_ */
+
+/* end of file c_eip74.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip96.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip96.h
new file mode 100644
index 0000000..6130c94
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip96.h
@@ -0,0 +1,50 @@
+/* c_eip96.h
+ *
+ * Default EIP-96 Driver Library configuration
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP96_H_
+#define C_EIP96_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip96.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+#endif /* C_EIP96_H_ */
+
+
+/* end of file c_eip96.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip97_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip97_global.h
new file mode 100644
index 0000000..c6525df
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/c_eip97_global.h
@@ -0,0 +1,426 @@
+/* c_eip97_global.h
+ *
+ * Default configuration parameters
+ * for the EIP-97 Global Control Driver Library
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef C_EIP97_GLOBAL_H_
+#define C_EIP97_GLOBAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_eip97_global.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-97 supported HW version
+#define EIP97_GLOBAL_MAJOR_VERSION           1
+#define EIP97_GLOBAL_MINOR_VERSION           0
+#define EIP97_GLOBAL_PATCH_LEVEL             0
+
+// EIP-202 supported HW version
+#define EIP202_GLOBAL_MAJOR_VERSION          1
+#define EIP202_GLOBAL_MINOR_VERSION          0
+#define EIP202_GLOBAL_PATCH_LEVEL            0
+
+// EIP-96 supported HW version
+#define EIP96_GLOBAL_MAJOR_VERSION           2
+#define EIP96_GLOBAL_MINOR_VERSION           0
+#define EIP96_GLOBAL_PATCH_LEVEL             3
+
+// Enables aggressive DMA mode. Set to 1 for optimal performance.
+#ifndef EIP97_GLOBAL_DFE_AGGRESSIVE_DMA_FLAG
+#define EIP97_GLOBAL_DFE_AGGRESSIVE_DMA_FLAG   1
+#endif
+
+// Enables DSE aggressive DMA mode. Set to 1 for optimal performance.
+#ifndef EIP97_GLOBAL_DSE_AGGRESSIVE_DMA_FLAG
+#define EIP97_GLOBAL_DSE_AGGRESSIVE_DMA_FLAG   1
+#endif
+
+// Bus burst size (bus type specific, AHB, AXI, PLB)
+// AHB:
+// Determines the maximum burst size that will be used on the AHB bus,
+// values „n‟ in the range 0...4 select 2^n beat maximum bursts (i.e. from
+// 1 to 16 beats) – other values are reserved and must not be used. The
+// system reset value of 4 selects 16 beat bursts.
+// AXI:
+// Determines the maximum burst size that will be used on the AXI
+// interface, values „n‟ in the range 1...4 select 2^n beat maximum bursts
+// (i.e. from 1 to 16 beats) – other values are reserved and must not be
+// used. The system reset value of 4 selects 16 beat bursts.
+// Maximum values:
+//    0100b - AXI v3 and AXI v4
+// PLB (YYZZb):
+// ZZ: Selects the maximum burst size on the PLB bus, value in range 00b – 11b:
+// 00b = 2 words, 01b = 4 words, 10b2 = 8 words, 11b = 16 words.
+// YY: Set data swap, value in range 00b – 11b:
+//     00b - swap 8-bit chunks within each 16-bit word
+//     01b - swap 8-bit chunks within each 32-bit word
+//     10b - swap 8-bit chunks within each 64-bit word (only if HDW>=001b)
+//     11b - swap 8-bit chunks within each 128-bit word (only if HDW>=010b)
+// This field cannot be changed when PLB Timeout, Write or Read error occurs
+#ifndef EIP97_GLOBAL_BUS_BURST_SIZE
+#define EIP97_GLOBAL_BUS_BURST_SIZE          7 // 7 for PLB
+#endif
+
+// Determines the maximum burst size that will be used on the receive side
+// of the AXI interface or
+// secondary requesting and priority for the PLB interface
+#ifndef EIP97_GLOBAL_RX_BUS_BURST_SIZE
+#define EIP97_GLOBAL_RX_BUS_BURST_SIZE       5 // 5 for PLB
+#endif
+
+// For AXI bus only, for non-AXI bus must be 0!
+// This field controls when an AXI read channel Master timeout Irq will be
+// generated. The minimum value is 1. The actual timeout fires when the last
+// data for a read transfer has not arrived within Timeout*(2^26) clock
+// cycles after the read command has been transferred.
+#ifndef EIP97_GLOBAL_TIMEOUT_VALUE
+#define EIP97_GLOBAL_TIMEOUT_VALUE           0xF
+#endif
+
+// Set this option to enable swapping of bytes in 32-bit words written via
+// the Packet Engine slave interface, e.g. device registers.
+//#define EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+
+// Set this option to disable the endianness conversion by the host
+// processor of the first words written to the Packet Engine registers
+// during its initialization.
+// If endianness conversion is configured for the Packet Engine Slave
+// interface (by defining the EIP97_GLOBAL_ENABLE_SWAP_REG_DATA parameter)
+// then also configure whether the endianness conversion is required
+// for the very first registers written during the Packet Engine
+// initialization, e.g. the Packet Engine registers used to reset
+// the engine and activate the endianness conversion for the Slave interface.
+//#define EIP97_GLOBAL_DISABLE_HOST_SWAP_INIT
+
+// Enable Flow Lookup Data Endianness Conversion
+// by the Classification Engine hardware master interface
+//#define EIP97_GLOBAL_BYTE_SWAP_FLUE_DATA
+
+// Enable Flow Record Data Endianness Conversion
+// by the Classification Engine hardware master interface
+//#define EIP97_GLOBAL_BYTE_SWAP_FLOW_DATA
+
+// Enable Context Data Endianness Conversion
+// by the Processing Engine hardware master interface
+//#define EIP97_GLOBAL_BYTE_SWAP_CONTEXT_DATA
+
+// Enable ARC4 Context Data Endianness Conversion
+// by the PE hardware master interface
+//#define EIP97_GLOBAL_BYTE_SWAP_ARC4_CONTEXT_DATA
+
+// One or several of the following methods must be configured:
+// Swap bytes within each 32 bit word
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_32
+// Swap 32 bit chunks within each 64 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_64
+// Swap 64 bit chunks within each 128 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_128
+// Swap 128 bit chunks within each 256 bit chunk
+//#define EIP97_GLOBAL_BYTE_SWAP_METHOD_256
+
+#if defined(EIP97_GLOBAL_BYTE_SWAP_METHOD_32)
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD   1
+#elif defined(EIP97_GLOBAL_BYTE_SWAP_METHOD_64)
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD   2
+#elif defined(EIP97_GLOBAL_BYTE_SWAP_METHOD_128)
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD   4
+#elif defined(EIP97_GLOBAL_BYTE_SWAP_METHOD_256)
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD   8
+#else
+#define EIP97_GLOBAL_BYTE_SWAP_METHOD   0
+#endif
+
+// if nonzero, packet update information (checksum, length, protocol) will
+// not be appended to packet data. Indicate in result token flags
+// which fields have to be updated.
+// If zero, such update information can be appended to the packet, if the
+// packet cannot be updated in-place by the hardware.
+#ifndef EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND
+#define EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND          0
+#endif
+
+// If nonzero, add an IP length delta field to the result token.
+#ifndef EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE
+#define EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE             0
+#endif
+
+// EIP-96 Packet Engine Enable extended errors
+// When set to 1 E14 indicates the presence of extended errors. If an extended
+//               error is present the error code is in E7..E0.
+// When set to 0 errors will always be reported one-hot in E14..E0
+#ifndef EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE
+#define EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE   0
+#endif
+
+// EIP-96 Packet Engine Timeout Counter
+// Enables the time-out counter that generates an error in case of a „hang‟
+// situation. If this bit is not set, the time-out error can never occur.
+#ifndef EIP97_GLOBAL_EIP96_TIMEOUT_CNTR_FLAG
+#define EIP97_GLOBAL_EIP96_TIMEOUT_CNTR_FLAG     1
+#endif
+
+// EIP-96 Packet Engine hold output data
+#ifndef EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA
+#define EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA      0
+#endif // EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA
+
+// Outbound sequence number threshold for reporting imminent rollover (32-bit)
+#ifndef EIP97_GLOBAL_EIP96_NUM32_THR
+#define EIP97_GLOBAL_EIP96_NUM32_THR                0
+#endif
+
+// Outbound sequence number threshold for reporting imminent rollover (64-bit)
+#ifndef EIP97_GLOBAL_EIP96_NUM64_THR_L
+#define EIP97_GLOBAL_EIP96_NUM64_THR_L              0
+#endif
+#ifndef EIP97_GLOBAL_EIP96_NUM64_THR_H
+#define EIP97_GLOBAL_EIP96_NUM64_THR_H              0
+#endif
+
+
+// Define this parameter to enable the EIP-97 HW version check
+//#define EIP97_GLOBAL_VERSION_CHECK_ENABLE
+
+// Define this parameter in order to configure the DFE and DSE ring priorities
+// Note: Some EIP-97 HW version do not have the DFE and DSE ring priority
+//       configuration registers.
+//#define EIP97_GLOBAL_DFE_DSE_PRIO_CONFIGURE
+
+// Set this parameter to a correct value in top-level configuration file
+// EIP-207s Classification Support, DMA Control base address
+//#define EIP97_RC_BASE      0x37000
+
+// Set this parameter to a correct value in top-level configuration file
+// EIP-207s Classification Support, DMA Control base address
+//#define EIP97_BASE         0x3FFF4
+
+// Read cache type control (EIP197_MST_CTRL rd_cache field)
+#ifndef EIP97_GLOBAL_RD_CACHE_VALUE
+#define EIP97_GLOBAL_RD_CACHE_VALUE                 0
+#endif
+
+// Write cache type control (EIP197_MST_CTRL wr_cache field)
+// Note: the buffering is enabled here by default
+#ifndef EIP97_GLOBAL_WR_CACHE_VALUE
+#define EIP97_GLOBAL_WR_CACHE_VALUE                 1
+#endif
+
+// Data read cache type control (data_cache_ctrl field in HIA_DFE_n_CFG reg)
+#ifndef EIP97_GLOBAL_DFE_DATA_CACHE_CTRL
+#define EIP97_GLOBAL_DFE_DATA_CACHE_CTRL            0
+#endif
+
+// Control read cache type control (ctrl_cache_ctrl field in HIA_DFE_n_CFG reg)
+#ifndef EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL
+#define EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL            0
+#endif
+
+// Data read cache type control (data_cache_ctrl field in HIA_DSE_n_CFG reg)
+#ifndef EIP97_GLOBAL_DSE_DATA_CACHE_CTRL
+#define EIP97_GLOBAL_DSE_DATA_CACHE_CTRL            0
+#endif
+
+// Data write bufferability control (buffer_ctrl field in HIA_DSE_n_CFG reg)
+// for the Look-Aside FIFO streaming interface only
+// Note: when the LA FIFO is not used then set this to 3 for optimal performance
+#ifndef EIP97_GLOBAL_DSE_BUFFER_CTRL
+#define EIP97_GLOBAL_DSE_BUFFER_CTRL                2
+#endif
+
+// Enables DSE single write mode. Set to 1 for optimal performance.
+// Note: This cannot be set to 1 when
+//       - 32-bit DMA address EIP-202 ring descriptor format is used
+//       - overlapping EIP-202 CDR/RDR rings are used
+#ifndef EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG
+#define EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG      0
+#endif
+
+// Number of the first ring used as a look-aside FIFO
+#ifndef EIP97_GLOBAL_LAFIFO_RING_ID
+#define EIP97_GLOBAL_LAFIFO_RING_ID                 1
+#endif
+
+// Number of Processing Engines to use
+// Maximum number of processing that should be used
+// Should not exceed the number of engines physically available
+#ifndef EIP97_GLOBAL_MAX_NOF_PE_TO_USE
+#define EIP97_GLOBAL_MAX_NOF_PE_TO_USE              1
+#endif
+
+// Number of the look-aside FIFO queues
+// EIP-197 configuration:
+//           Server b - 1, c - 3, d - 5, e - 1.
+//           Mobile 0
+#ifndef EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE
+#define EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE          0
+#endif
+
+// Number of the Inline FIFO queues
+// Server 1 Mobile 0
+#ifndef EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE
+#define EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE          0
+#endif
+
+// AXI bus protection value, refer to HW documentation
+#ifndef EIP97_GLOBAL_SUPPORT_PROTECT_VALUE
+#define EIP97_GLOBAL_SUPPORT_PROTECT_VALUE          0
+#endif
+
+// Look-aside FIFO descriptor data swap
+#ifndef EIP202_LASIDE_DSCR_BYTE_SWAP_METHOD
+#define EIP202_LASIDE_DSCR_BYTE_SWAP_METHOD      EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+// Look-aside FIFO input packet data swap
+#ifndef EIP202_LASIDE_IN_PKT_BYTE_SWAP_METHOD
+#define EIP202_LASIDE_IN_PKT_BYTE_SWAP_METHOD    EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+// Look-aside FIFO output packet data swap
+#ifndef EIP202_LASIDE_OUT_PKT_BYTE_SWAP_METHOD
+#define EIP202_LASIDE_OUT_PKT_BYTE_SWAP_METHOD   EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+// Look-aside FIFO token data swap
+#ifndef EIP202_LASIDE_TOKEN_BYTE_SWAP_METHOD
+#define EIP202_LASIDE_TOKEN_BYTE_SWAP_METHOD     EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+// Look-aside FIFO input packet data AXI PROT value
+#ifndef EIP202_LASIDE_IN_PKT_PROTO
+#define EIP202_LASIDE_IN_PKT_PROTO                  0
+#endif
+
+// Look-aside FIFO output packet data AXI PROT value
+#ifndef EIP202_LASIDE_OUT_PKT_PROTO
+#define EIP202_LASIDE_OUT_PKT_PROTO                 0
+#endif
+
+// Look-aside FIFO token data AXI PROT value
+#ifndef EIP202_LASIDE_TOKEN_PROTO
+#define EIP202_LASIDE_TOKEN_PROTO                   0
+#endif
+
+// Inline FIFO: burst size 3 = 8 beats = 128 bytes
+#ifndef EIP202_INLINE_BURST_SIZE
+#define EIP202_INLINE_BURST_SIZE                    3
+#endif
+
+// Inline FIFO: result packets in order - 1, out of order - 0
+#ifndef EIP202_INLINE_FORCE_INORDER
+#define EIP202_INLINE_FORCE_INORDER                 0  // out of order
+#endif
+
+// Inline FIFO input packet data swap
+#ifndef EIP202_INLINE_IN_PKT_BYTE_SWAP_METHOD
+#define EIP202_INLINE_IN_PKT_BYTE_SWAP_METHOD    EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+// Inline FIFO output packet data swap
+#ifndef EIP202_INLINE_OUT_PKT_BYTE_SWAP_METHOD
+#define EIP202_INLINE_OUT_PKT_BYTE_SWAP_METHOD   EIP97_GLOBAL_BYTE_SWAP_METHOD
+#endif
+
+//Define if the hardware ECN registers are included
+//#define EIP97_GLOBAL_HAVE_ECN_FIXUP
+
+// Do not wait for token in EIP96
+#ifndef EIP97_GLOBAL_EIP96_NO_TOKEN_WAIT
+#define EIP97_GLOBAL_EIP96_NO_TOKEN_WAIT false
+#endif
+
+#ifndef EIP97_GLOBAL_EIP96_ECN_CONTROL
+#define EIP97_GLOBAL_EIP96_ECN_CONTROL 0x1f
+#endif
+
+#if EIP97_GLOBAL_EIP96_ECN_CONTROL & 0x1
+#define EIP96_ECN_CLE0 20
+#else
+#define EIP96_ECN_CLE0 0
+#endif
+#if EIP97_GLOBAL_EIP96_ECN_CONTROL & 0x2
+#define EIP96_ECN_CLE1 21
+#else
+#define EIP96_ECN_CLE1 0
+#endif
+#if EIP97_GLOBAL_EIP96_ECN_CONTROL & 0x4
+#define EIP96_ECN_CLE2 22
+#else
+#define EIP96_ECN_CLE2 0
+#endif
+#if EIP97_GLOBAL_EIP96_ECN_CONTROL & 0x8
+#define EIP96_ECN_CLE3 23
+#else
+#define EIP96_ECN_CLE3 0
+#endif
+#if EIP97_GLOBAL_EIP96_ECN_CONTROL & 0x10
+#define EIP96_ECN_CLE4 24
+#else
+#define EIP96_ECN_CLE4 0
+#endif
+
+// DFE packet threshold
+#ifndef EIP97_GLOBAL_IN_TBUF_PKT_THR
+#define EIP97_GLOBAL_IN_TBUF_PKT_THR 0
+#endif
+
+// Send context done pulses to record cache.
+#ifndef EIP97_GLOBAL_EIP96_CTX_DONE_PULSE
+#define EIP97_GLOBAL_EIP96_CTX_DONE_PULSE false
+#endif
+
+#ifndef EIP97_GLOBAL_META_DATA_ENABLE
+#define EIP97_GLOBAL_META_DATA_ENABLE 0
+#endif
+
+// Strict argument checking for the input parameters
+// If required then define this parameter in the top-level configuration
+//#define EIP97_GLOBAL_STRICT_ARGS
+
+// Finite State Machine that can be used for verifying that the Driver Library
+// API is called in a correct order
+//#define EIP97_GLOBAL_DEBUG_FSM
+
+#ifndef EIP97_EIP96_CTX_SIZE
+#define EIP97_EIP96_CTX_SIZE 0x3e
+#endif
+
+#endif /* C_EIP97_GLOBAL_H_ */
+
+
+/* end of file c_eip97_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip201.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip201.h
new file mode 100644
index 0000000..79c52af
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip201.h
@@ -0,0 +1,318 @@
+/* eip201.h
+ *
+ * EIP201 Driver Library API
+ *
+ * Security-IP-201 is the Advanced Interrupt Controller (AIC)
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_EIP201_H
+#define INCLUDE_GUARD_EIP201_H
+
+// Basic definitions
+#include "basic_defs.h"          // uint32_t, bool, static inline, BIT_* etc.
+// Device API definitions
+#include "device_types.h"        // Device_Handle_t
+
+// The API's table of contents:
+//
+//  EIP201_Status_t - error codes data type
+//  EIP201_Source_t - interrupt source (irq) data type
+//  EIP201_Config API - to control individual configurations
+//  EIP201_SourceMask API - to control individual interrupt masks (masking)
+//  EIP201_SourceStatus API - to retrieve individual interrupt statuses
+//  EIP201_Initialize API - to initialize the EIP201 device by providing
+//                          initial interrupt polarities and masks
+//                          just in one call
+//  EIP201_Acknowledge - to acknowledge individual interrupts
+
+
+/*----------------------------------------------------------------------------
+ * List of EIP-201 error codes that API functions can return.
+ * EIP201_STATUS_UNSUPPORTED_IRQ can be returned if a concrete EIP device
+ * does not support an interrupt source number provided in a bitmap
+ * as a function argument.
+ *
+ * Any other integer value: Error return from device read or write function.
+ */
+enum
+{
+    EIP201_STATUS_SUCCESS = 0,
+    EIP201_STATUS_UNSUPPORTED_IRQ,
+    EIP201_STATUS_UNSUPPORTED_HARDWARE_VERSION,
+};
+typedef int EIP201_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * List of EIP-201 interrupt sources
+ * Maximum number of sources is 32.
+ */
+
+// a single EIP201 interrupt source, typically BIT_xx
+typedef uint32_t EIP201_Source_t;
+
+// An OR-ed combination of EIP201 interrupt sources
+typedef uint32_t EIP201_SourceBitmap_t;
+
+// A handy macro for all interrupt sources mask
+#define EIP201_SOURCE_ALL  (EIP201_SourceBitmap_t)(~0)
+
+//Note1:
+//  In API functions to follow the first parameter often is
+//  Device_Handle_t Device.
+//  This is a context object for the Driver Framework Device API
+//  implementation.
+//  This context must be unique for each instance of each driver
+//  to allow selection of a specific EIP device (instance).
+//  It is important that the Device_Handle_t instance describes a
+//  valid EIP-201 device (HW block).
+
+//Note2:
+//  In API functions to follow the second parameter sometimes is
+//  const EIP201_SourceBitmap_t Sources.
+//  This is always a set of interrupt sources, for which some operation
+//  has to be performed.
+//  If an interrupt source is not included in the EIP201_SourceBitmap_t
+//  instance, then the operation will not be performed for this source
+//  (corresponding bit is not changed in a HW register).
+
+//Note3:
+//  If not stated otherwise, all API functions are re-entrant and can be
+//  called concurrently with other API functions.
+
+/*----------------------------------------------------------------------------
+ * EIP201_Config API
+ *
+ * Controls configuration of individual interrupt sources:
+ * - Falling Edge or Rising Edge (edge based)
+ * - Active High or Active Low (level based)
+ *
+ * Usage:
+ *     EIP201_Config_t Source0Config;
+ *
+ *     EIP201_Config_Change(
+ *             Device,
+ *             BIT_0,
+ *             EIP201_CONFIG_ACTIVE_LOW);
+ *
+ *     EIP201_Config_Change(
+ *             Device,
+ *             BIT_1 | BIT_2,
+ *             EIP201_CONFIG_RISING_EDGE);
+ *
+ *     Source0Config = EIP201_Config_Read(Device, BIT_0);
+ */
+typedef enum
+{
+    EIP201_CONFIG_ACTIVE_LOW = 0,
+    EIP201_CONFIG_ACTIVE_HIGH,
+    EIP201_CONFIG_FALLING_EDGE,
+    EIP201_CONFIG_RISING_EDGE
+} EIP201_Config_t;
+
+/* EIP201_Config_Change function is not re-entrant and
+   cannot be called concurrently with API functions:
+        EIP201_Initialize
+*/
+EIP201_Status_t
+EIP201_Config_Change(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources,
+        const EIP201_Config_t NewConfig);
+
+// Source can only have one bit set
+EIP201_Config_t
+EIP201_Config_Read(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source);
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask API
+ *
+ * Allows masking/unmasking individual interrupt sources.
+ *
+ * Usage:
+ *     bool Source0IsEnabled;
+ *     EIP201_SourceBitmap_t AllEnabledSources;
+ *     EIP201_SourceMask_EnableSource(Device, BIT_1 + BIT_0);
+ *     EIP201_SourceMask_DisableSource(Device, BIT_5 + BIT_2);
+ *     Source0IsEnabled = EIP201_SourceMask_SourceIsEnabled(Device, BIT_0);
+ *     AllEnabledSources = EIP201_SourceMask_ReadAll(Device);
+ */
+
+/* EIP201_SourceMask_EnableSource
+*/
+EIP201_Status_t
+EIP201_SourceMask_EnableSource(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources);
+
+/* EIP201_SourceMask_DisableSource
+*/
+EIP201_Status_t
+EIP201_SourceMask_DisableSource(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources);
+
+// Source can only have one bit set
+bool
+EIP201_SourceMask_SourceIsEnabled(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source);
+
+// Returns a bitmask for all enabled sources.
+// In this bitmask:
+//      0 - an interrupt source is disabled
+//      1 - an interrupt source is enabled
+EIP201_SourceBitmap_t
+EIP201_SourceMask_ReadAll(
+        Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus API
+ *
+ * Allows reading status of individual interrupt sources.
+ * _IsEnabledSourcePending -
+ *     reads the status of the source after a source mask is applied.
+ * _IsRawSourcePending -
+ *     reads the status of the raw source (no source mask is applied).
+ *
+ * Usage:
+ *     bool Source0EnabledStatus;
+ *     bool Source0RawStatus;
+ *     EIP201_SourceBitmap_t AllEnabledStatuses;
+ *     EIP201_SourceBitmap_t AllRawStatuses;
+ *     Source0EnabledStatus =
+ *         EIP201_SourceStatus_IsEnabledSourcePending(Device, BIT_0);
+ *     Source0RawStatus =
+ *         EIP201_SourceStatus_IsRawSourcePending(Device, BIT_0);
+ *     AllEnabledStatuses = EIP201_SourceStatus_ReadAllEnabled(Device);
+ *     AllRawStatuses = EIP201_SourceStatus_ReadAllRaw(Device);
+ */
+// Source can only have one bit set
+bool
+EIP201_SourceStatus_IsEnabledSourcePending(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source);
+
+// Source can only have one bit set
+bool
+EIP201_SourceStatus_IsRawSourcePending(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source);
+
+// Returns a bitmask for current statuses of all enabled sources.
+// (after a source mask is applied)
+// In this bitmask:
+//      0 - an enabled interrupt source is not pending (inactive).
+//      1 - an enabled interrupt source is pending (active).
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllEnabled(
+        Device_Handle_t Device);
+
+// Returns a bitmask for current statuses of all raw sources.
+// (no source mask is applied)
+// In this bitmask:
+//      0 - a raw interrupt source is not pending (inactive).
+//      1 - a raw interrupt source is pending (active).
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllRaw(
+        Device_Handle_t Device);
+
+
+// Returns a bitmask for current statuses of all enabled sources.
+// (after a source mask is applied). Also return a status.
+// In this bitmask:
+//      0 - an enabled interrupt source is not pending (inactive).
+//      1 - an enabled interrupt source is pending (active).
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllEnabledCheck(
+        Device_Handle_t Device,
+        EIP201_SourceBitmap_t * const Statuses_p);
+
+// Returns a bitmask for current statuses of all raw sources.
+// (no source mask is applied). Also return a status.
+// In this bitmask:
+//      0 - a raw interrupt source is not pending (inactive).
+//      1 - a raw interrupt source is pending (active).
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllRawCheck(
+        Device_Handle_t Device,
+        EIP201_SourceBitmap_t * const Statuses_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Initialize API
+ *
+ * Initializes the EIP201 interrupt controller device.
+ *
+ *     SettingsArray_p
+ *         Initial interrupt settings for a number of interrupt sources.
+ *         Can be NULL. If NULL, all settings are device default.
+ *
+ *     SettingsCount
+ *         Number of interrupt sources, for which settings are given.
+ *         Can be 0. If 0, all settings are device default.
+ *
+ * Usage:
+ *     EIP201_SourceSettings_t MySettings[] =
+ *     {
+ *         {BIT_1, EIP201_CONFIG_ACTIVE_LOW,  false},
+ *         {BIT_2, EIP201_CONFIG_ACTIVE_HIGH, true}
+ *     };
+ *
+ *     EIP201_Initialize(Device, MySettings, 2);
+ */
+typedef struct
+{
+    EIP201_Source_t Source;  // for which interrupt source the settings are
+    EIP201_Config_t Config;
+    bool fEnable;
+} EIP201_SourceSettings_t;
+
+/* EIP201_Initialize function is not re-entrant and
+   cannot be called concurrently with API functions:
+        EIP201_Config_Change
+*/
+EIP201_Status_t
+EIP201_Initialize(
+        Device_Handle_t Device,
+        const EIP201_SourceSettings_t * SettingsArray_p,
+        const unsigned int SettingsCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Acknowledge
+ *
+ * Acknowledges the EIP201 interrupts.
+ *
+ * Usage:
+ *     EIP201_Acknowledge(Device, BIT_0 | BIT_1);
+ */
+EIP201_Status_t
+EIP201_Acknowledge(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources);
+
+#endif /* INCLUDE_GUARD_EIP201_H */
+
+/* end of file eip201.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cd_format.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cd_format.h
new file mode 100644
index 0000000..2fb475c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cd_format.h
@@ -0,0 +1,101 @@
+/* eip202_cd_format.h
+ *
+ * EIP-202 Ring Control Driver Library Command Descriptor Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_CD_FORMAT_H_
+#define EIP202_CD_FORMAT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_cdr.h"                // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"              // DMAResource_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Make_ControlWord
+ *
+ * This helper function returns the Control Word that can be written to
+ * the EIP-202 Command Descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_CD_Make_ControlWord(
+        const uint8_t TokenWordCount,
+        const uint32_t SegmentByteCount,
+        const bool fFirstSegment,
+        const bool fLastSegment,
+        const bool fForceEngine,
+        const uint8_t EngineId);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Write
+ *
+ * This helper function writes the EIP-202 Logical Command Descriptor to the CDR
+ *
+ * This function is not re-entrant.
+ *
+ */
+void
+EIP202_CD_Write(
+        DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const EIP202_ARM_CommandDescriptor_t * const Descr_p,
+        const bool fATP);
+
+
+#endif /* EIP202_CD_FORMAT_H_ */
+
+
+/* end of file eip202_cd_format.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr.h
new file mode 100644
index 0000000..74a4ede
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr.h
@@ -0,0 +1,561 @@
+/* eip202_cdr.h
+ *
+ * EIP-202 Driver Library API:
+ * Command Descriptor Ring (CDR)
+ *
+ * All the CDR API functions can be used concurrently with the RDR API functions
+ * for any ring interface ID unless the API function description states
+ * otherwise.
+ *
+ * Refer to the EIP-202 Driver Library User Guide for more information about
+ * usage of this API.
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_CDR_H_
+#define EIP202_CDR_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+// EIP-202 Ring Control Driver Library Common Types API
+#include "eip202_ring_types.h"       // EIP202_* common types
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Command descriptor Control Data size (in 32-bit words)
+// Note: This is valid for ATP mode only!
+#ifdef EIP202_64BIT_DEVICE
+#define EIP202_CD_CTRL_DATA_MAX_WORD_COUNT  6
+#else
+#define EIP202_CD_CTRL_DATA_MAX_WORD_COUNT  3
+#endif // !EIP202_64BIT_DEVICE
+
+// CDR Status information
+typedef struct
+{
+    // Fatal errors (interrupts), set to true when pending
+    // CDR must be re-initialized in case of a fatal error
+    bool fDMAError;
+    bool fError;
+    bool fOUFlowError;
+
+    // Threshold Interrupt, set to true when pending
+    bool fTresholdInt;
+
+    // Timeout Interrupt, set to true when pending
+    bool fTimeoutInt;
+
+    // Number of 32-bit words that are currently free
+    // in the Command Descriptor FIFO
+    uint16_t CDFIFOWordCount;
+
+    // Number of valid 32-bit Prepared Command Descriptor words that
+    // are prepared in the CDR
+    uint32_t CDPrepWordCount;
+
+    // Number of valid 32-bit Processed Command Descriptor words that
+    // are processed in the CDR
+    uint32_t CDProcWordCount;
+
+    // Number of full packets (i.e. the number of descriptors marked Last)
+    // that are fully processed by the DFE and not yet acknowledged by Host.
+    // If more than 127 packets are processed this field returns the value 127.
+    uint8_t CDProcPktWordCount;
+} EIP202_CDR_Status_t;
+
+// CDR settings
+typedef struct
+{
+    // Additional Token Pointer Descriptor Mode
+    // When true the token data can be stored in a separate from the descriptor
+    // DMA buffer
+    bool                        fATP;
+
+    // When true then the tokens consisting out of 1 or 2 32-bit words
+    // can be passed to the PE directly via the command descriptor
+    bool                        fATPtoToken;
+
+    // Other ARM settings
+    EIP202_ARM_Ring_Settings_t  Params;
+
+} EIP202_CDR_Settings_t;
+
+// Control word parameters for the Logical Command Descriptor
+typedef struct
+{
+    // Set to true for the first descriptor in the descriptor chain
+    bool        fFirstSegment;
+
+    // Set to true for the last descriptor in the descriptor chain
+    bool        fLastSegment;
+
+    // Segment size in bytes, can be 0 for an empty segment
+    uint32_t    SegmentByteCount;
+
+    // Token size in 32-bit words,
+    // important for the first segment only but can be 0 too,
+    // must be always 0 for the non-first segments
+    uint8_t     TokenWordCount;
+
+    // Force the command to be processed on a specific engine.
+    bool        fForceEngine;
+
+    // Engine ID to process the command on.
+    uint8_t     EngineId;
+
+} EIP202_CDR_Control_t;
+
+// Logical Command Descriptor
+typedef struct
+{
+    // control fields for the command descriptor
+    // EIP202_CDR_Write_ControlWord() helper function
+    // can be used for obtaining this word
+    uint32_t ControlWord;
+
+    // Token header word
+    uint32_t TokenHeader;
+
+    // This parameter is copied through from command to result descriptor
+    // unless EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS configuration parameter
+    // is defined in c_eip202_ring.h
+    uint32_t ApplicationId;
+
+    // Source packet data length, in bytes
+    unsigned int SrcPacketByteCount;
+
+    // Source packet data, has to be provided by the caller:
+    // Physical address that can be used by Device DMA
+    EIP202_DeviceAddress_t SrcPacketAddr;
+
+    // Context Data DMA buffer, has to be allocated and filled in by the caller
+    // Physical address that can be used by Device DMA
+    EIP202_DeviceAddress_t TokenDataAddr;
+
+    // Context Data DMA buffer, has to be allocated and filled in by the caller
+    // Physical address that can be used by Device DMA
+    EIP202_DeviceAddress_t ContextDataAddr;
+
+    // Input Token buffer with fixed size
+    uint32_t * Token_p;
+
+} EIP202_ARM_CommandDescriptor_t;
+
+
+/*----------------------------------------------------------------------------
+ * CDR Initialization API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Init
+ *
+ * This function performs the initialization of the EIP-202 CDR
+ * interface and transits the API to the Initialized state.
+ *
+ * This function returns the EIP202_RING_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Ring Control Driver Library configuration.
+ *
+ * Note: This function should be called either after the EIP-202 HW Reset or
+ *       after the Ring SW Reset, see the EIP202_CDR_Reset() function.
+ *       This function as well as optionally EIP202_CDR_Reset() function must be
+ *       executed before any other of the EIP202_CDR_*() functions can be called.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_CDR_Reset() function for the same Device.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance identified by the Device parameter.
+ *
+ * Device (input)
+ *     Handle for the Ring Control device instance returned by Device_Find
+ *     for this CDR instance.
+ *
+ * CDRSettings_p (input)
+ *     Pointer to the data structure that contains CDR configuration parameters
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Init(
+        EIP202_Ring_IOArea_t * IOArea_p,
+        const Device_Handle_t Device,
+        const EIP202_CDR_Settings_t * const CDRSettings_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Reset
+ *
+ * This function performs the CDR SW Reset and transits the API
+ * to the Uninitialized state. This function must be called before using
+ * the other CDR API functions if the state of the ring is Unknown.
+ *
+ * This function can be used to recover the CDR from a fatal error.
+ *
+ * Note: This function must be called before calling the EIP202_CDR_Init()
+ *       function only if the EIP-202 HW Reset was not done. Otherwise it still
+ *       is can be called but it is not necessary.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_CDR_Init() function for the same Device.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance identified by the Device parameter.
+ *
+ * Device (input)
+ *     Handle for the Ring Control device instance returned by Device_Find
+ *     for this CDR instance.
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Reset(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Options_Get
+ *
+ * This function reads the local options register of the CDR device and
+ * returns the information in a data structure of type EIP202_Ring_Options_t.
+ *
+ * Note: the options register (and therefore this function) is not available
+ *       in all versions of the EIP202.
+ *
+ * This function can be called in any state, even when the device is not
+ * yet initialized.
+ *
+ * Device (input)
+ *     Handle for the Ring Control device instance returned by Device_Find
+ *     for this CDR instance.
+ *
+ * Options_p (output)
+ *     Pointer to the options data structure to be filled in by this
+ *     function.
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Options_Get(
+        const Device_Handle_t Device,
+        EIP202_Ring_Options_t * const Options_p);
+
+
+/*----------------------------------------------------------------------------
+ * CDR Descriptor I/O API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Get
+ *
+ * This function outputs the fill level of the ring requested by means of
+ * the Device parameter in the I/O Area. The fill level is obtained as a number
+ * of command descriptors that have been submitted by the Host to the CDR but
+ * not processed by the device yet.
+ *
+ * When the CDR is in the "Ring Full" state this function outputs the fill
+ * level equal to the CDR size. When the CDR is in the "Ring Empty" state this
+ * functions outputs the zero fill level. the CDR is in the "Ring Free" state
+ * when this function returns the fill level that is greater than zero and less
+ * than the CDR size (in command descriptors).
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_CDR_Descriptor_Put() function for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance which contains the Device handle.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of command
+ *     descriptors pending in the CDR will be stored
+ *     CDR Empty: FillLevel = 0
+ *     CDR Free:  0 < FillLevel < RingSize (in descriptors)
+ *     CDR Full:  FillLevel = RingSize (in descriptors)
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Write_ControlWord
+ *
+ * This helper function returns the control word that can be written to
+ * the logical command descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_CDR_Write_ControlWord(
+        const EIP202_CDR_Control_t * const  CommandCtrl_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Descriptor_Put
+ *
+ * This function puts a requested number of command descriptors to the CDR.
+ * The function returns EIP202_RING_NO_ERROR and zero descriptors done count
+ * (*DscrDoneCount_p set to 0) when no descriptors can be added to the CDR,
+ * e.g. "Ring Full" state.
+ *
+ * This function can be called after the EIP202_CDR_FillLevel_Get()
+ * function when the latter checks how many command descriptors can be added
+ * to the CDR.
+ *
+ * The execution context calling this API function must
+ *
+ * 1) Provide input data via the CDR using the EIP202_CDR_Descriptor_Put()
+ * function before it or another context can obtain output data from the RDR.
+ * This requirement is relevant for the look-aside use case only.
+ *
+ * 2) Ensure that the Token Data, Packet Data and Context Data DMA buffers are
+ * not re-used or freed by it or another context until the processed result
+ * descriptor(s) referring to the packet associated with these buffers is(are)
+ * fully processed by the Device. This is required not only when in-place
+ * packet transform is done using the same Packet Data DMA buffer as input and
+ * output buffer but also when different DMA buffers are used for the packet
+ * processing input and output data.
+ *
+ * 3) Keep the packet descriptor chain state consistent. All descriptors that
+ * belong to the same packet must be submitted atomically into the CDR without
+ * being intermixed with descriptors that belong to other packets.
+ *
+ * 4) Submit the descriptors that belong to the same packet descriptor chain in
+ * the right order, e.g. first descriptor for the first segment followed by
+ * the middle descriptors followed by the last descriptor.
+ *
+ * 5) Ensure it does not call this function concurrently with another context
+ * for the same Device.
+ *
+ * 6) Ensure it does not call this function concurrently with another context
+ * calling the EIP202_CDR_FillLevel_Get() function for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance which contains the Device handle.
+ *
+ * CommandDscr_p (input)
+ *     Pointer to 1st in the the array of command descriptors.
+ *
+ * DscrRequestedCount (input)
+ *     Number of descriptors stored back-to-back in the array
+ *     pointed to by CommandDscr_p.
+ *
+ * DscrDoneCount_p (output)
+ *     Pointer to the memory location where the number of descriptors
+ *     actually added to the CDR will be stored.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of command
+ *     descriptors pending in the CDR will be stored
+ *     CDR Empty: FillLevel = 0
+ *     CDR Free:  0 < FillLevel < RingSize (in descriptors)
+ *     CDR Full:  FillLevel = RingSize (in descriptors)
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : feature is not supported
+ *     EIP202_RING_ARGUMENT_ERROR : passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Descriptor_Put(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const EIP202_ARM_CommandDescriptor_t * CommandDscr_p,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrDoneCount_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * CDR Event Management API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Status_Get
+ *
+ * This function retrieves the CDR status information. It can be called
+ * periodically to monitor the CDR status and occurrence of fatal errors.
+ *
+ * In case of a fatal error the EIP202_CDR_Reset() function can be called to
+ * recover the CDR and bring it to the sane and safe state.
+ * The RDR SW Reset by means of the EIP202_RDR_Reset() function as well
+ * as the Global SW Reset by means of the EIP202_Global_Reset() function
+ * or the HW Reset must be performed too.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for this CDR instance which contains the Device handle.
+ *
+ * Status_p (output)
+ *     Pointer to the memory location where the CDR status information
+ *     will be stored
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Status_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_CDR_Status_t * const Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_Enable
+ *
+ * This function enables the Command Descriptor Threshold and Timeout
+ * interrupts. This function does not change the current API state. It must
+ * be called every time after the CDR Threshold or Timeout interrupt occurs
+ * in order to re-enable these one-shot interrupts.
+ *
+ * The CDR Manager interrupts are routed to the EIP-201 Advanced Interrupt
+ * Controller (AIC) which in its turn can be connected to a System Interrupt
+ * Controller (SIC).
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance which contains the Device handle.
+ *
+ * ThresholdDscrCount (input)
+ *     When the CDR descriptor fill level reaches the value below the number
+ *     specified by this parameter the CDR Threshold interrupt (cdr_thresh_irq)
+ *     will be generated.
+ *
+ * Timeout (input)
+ *     When the CDR descriptor fill level is non-zero and not decremented
+ *     for the amount of time specified by this parameter the CDR Timeout
+ *     interrupt (cdr_timeout_irq) will be generated.
+ *     The timeout value must be specified in 256 clock cycles
+ *     of the EIP-202 HIA clock.
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_Enable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const unsigned int ThresholdDscrCount,
+        const unsigned int Timeout);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_ClearAndDisable
+ *
+ * This function clears and disables the Command Descriptor
+ * Threshold (cdr_thresh_irq) and Timeout (cdr_timeout_irq) interrupts.
+ * This function does not change the current API state.
+ *
+ * This function must be called as soon as the Command Descriptor Threshold or
+ * Timeout interrupt occurs. The occurrence of these interrupts can be detected
+ * by means of the EIP202_CDR_Status_Get() function, for example from an
+ * Interrupt Service Routine.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the CDR instance which contains the Device handle.
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_ClearAndDisable(
+        EIP202_Ring_IOArea_t * const IOArea_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Dump
+ *
+ */
+void
+EIP202_CDR_Dump(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RingAdmin_t * const RingAdmin_p);
+
+
+/* end of file eip202_cdr.h */
+
+
+#endif /* EIP202_CDR_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_dscr.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_dscr.h
new file mode 100644
index 0000000..70d81f6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_dscr.h
@@ -0,0 +1,100 @@
+/* eip202_cdr_dscr.h
+ *
+ * EIP-202 Ring Control Driver Library API Command Descriptor Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_CDR_DSCR_H_
+#define EIP202_CDR_DSCR_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_WriteCB
+ * A write callback for the Ring Helper
+ */
+int
+EIP202_CDR_WriteCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int WriteIndex,
+        const unsigned int WriteCount,
+        const unsigned int TotalWriteLimit,
+        const void * Descriptors_p,
+        const int DescriptorCount,
+        const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_ReadCB
+ * A read callback for the Ring Helper
+ */
+int
+EIP202_CDR_ReadCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int ReadIndex,
+        const unsigned int ReadLimit,
+        void * Descriptors_p,
+        const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_StatusCB
+ * A status callback for the Ring Helper
+ */
+
+int
+EIP202_CDR_StatusCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        int * const DeviceReadPos_p);
+
+
+#endif /* EIP202_CDR_DSCR_H_ */
+
+
+/* end of file eip202_cdr_dscr.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_fsm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_fsm.h
new file mode 100644
index 0000000..09d2bc7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_fsm.h
@@ -0,0 +1,76 @@
+/* eip202_cdr_fsm.h
+ *
+ * EIP-202 Ring Control Driver Library API State Machine Internal Interface
+ * for Command Descriptor Ring (CDR)
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_CDR_FSM_H_
+#define EIP202_CDR_FSM_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "eip202_ring_types.h"            // EIP202_Ring_Error_t
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-202 Ring Control Driver Library API States
+typedef enum
+{
+    EIP202_CDR_STATE_UNKNOWN = 1,
+    EIP202_CDR_STATE_UNINITIALIZED,
+    EIP202_CDR_STATE_INITIALIZED,
+    EIP202_CDR_STATE_FREE,
+    EIP202_CDR_STATE_FULL,
+    EIP202_CDR_STATE_FATAL_ERROR
+} EIP202_CDR_State_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_State_Set
+ *
+ * This function check whether the transition from the "CurrentState" to the
+ * "NewState" is allowed and if yes changes the former to the latter.
+ *
+  * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ILLEGAL_IN_STATE : state transition is not allowed
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_State_Set(
+        volatile EIP202_CDR_State_t * const CurrentState,
+        const EIP202_CDR_State_t NewState);
+
+
+#endif /* EIP202_CDR_FSM_H_ */
+
+
+/* end of file eip202_cdr_fsm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_level0.h
new file mode 100644
index 0000000..2884725
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_cdr_level0.h
@@ -0,0 +1,543 @@
+/* eip202_cdr_level0.h
+ *
+ * EIP-202 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_CDR_LEVEL0_H_
+#define EIP202_CDR_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+#include "device_swap.h"        // Device_SwapEndian32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-202 HIA CDR registers
+ *****************************************************************************/
+
+#define EIP202_CDR_OFFS           4
+
+// 2 KB MMIO space for one CDR instance
+#define EIP202_CDR_BASE                   0x00000000
+#define EIP202_CDR_RING_BASE_ADDR_LO      ((EIP202_CDR_BASE) + \
+                                            (0x00 * EIP202_CDR_OFFS))
+#define EIP202_CDR_RING_BASE_ADDR_HI      ((EIP202_CDR_BASE) + \
+                                            (0x01 * EIP202_CDR_OFFS))
+#define EIP202_CDR_DATA_BASE_ADDR_LO      ((EIP202_CDR_BASE) + \
+                                            (0x02 * EIP202_CDR_OFFS))
+#define EIP202_CDR_DATA_BASE_ADDR_HI      ((EIP202_CDR_BASE) + \
+                                            (0x03 * EIP202_CDR_OFFS))
+#define EIP202_CDR_ATOK_BASE_ADDR_LO      ((EIP202_CDR_BASE) + \
+                                            (0x04 * EIP202_CDR_OFFS))
+#define EIP202_CDR_ATOK_BASE_ADDR_HI      ((EIP202_CDR_BASE) + \
+                                            (0x05 * EIP202_CDR_OFFS))
+#define EIP202_CDR_RING_SIZE              ((EIP202_CDR_BASE) + \
+                                            (0x06 * EIP202_CDR_OFFS))
+#define EIP202_CDR_DESC_SIZE              ((EIP202_CDR_BASE) + \
+                                            (0x07 * EIP202_CDR_OFFS))
+#define EIP202_CDR_CFG                    ((EIP202_CDR_BASE) + \
+                                            (0x08 * EIP202_CDR_OFFS))
+#define EIP202_CDR_DMA_CFG                ((EIP202_CDR_BASE) + \
+                                            (0x09 * EIP202_CDR_OFFS))
+#define EIP202_CDR_THRESH                 ((EIP202_CDR_BASE) + \
+                                            (0x0A * EIP202_CDR_OFFS))
+#define EIP202_CDR_COUNT                  ((EIP202_CDR_BASE) + \
+                                            (0x0B * EIP202_CDR_OFFS))
+#define EIP202_CDR_PROC_COUNT             ((EIP202_CDR_BASE) + \
+                                            (0x0C * EIP202_CDR_OFFS))
+#define EIP202_CDR_POINTER                ((EIP202_CDR_BASE) + \
+                                            (0x0D * EIP202_CDR_OFFS))
+#define EIP202_CDR_STAT                   ((EIP202_CDR_BASE) + \
+                                            (0x0F * EIP202_CDR_OFFS))
+#define EIP202_CDR_OPTIONS                ((EIP202_CDR_BASE) + \
+                                            (0x1FE* EIP202_CDR_OFFS))
+#define EIP202_CDR_VERSION                ((EIP202_CDR_BASE) + \
+                                            (0x1FF * EIP202_CDR_OFFS))
+
+// EIP-202 HIA EIP number (0xCA) and complement (0x35)
+#define EIP202_CDR_SIGNATURE              ((uint16_t)0x35CA)
+
+
+// Default EIP202_CDR_x register values
+#define EIP202_CDR_RING_BASE_ADDR_LO_DEFAULT       0x00000000
+#define EIP202_CDR_RING_BASE_ADDR_HI_DEFAULT       0x00000000
+#define EIP202_CDR_DATA_BASE_ADDR_LO_DEFAULT       0x00000000
+#define EIP202_CDR_DATA_BASE_ADDR_HI_DEFAULT       0x00000000
+#define EIP202_CDR_ATOK_BASE_ADDR_LO_DEFAULT       0x00000000
+#define EIP202_CDR_ATOK_BASE_ADDR_HI_DEFAULT       0x00000000
+#define EIP202_CDR_RING_SIZE_DEFAULT               0x00000000
+#define EIP202_CDR_DESC_SIZE_DEFAULT               0x00000000
+#define EIP202_CDR_CFG_DEFAULT                     0x00000000
+#define EIP202_CDR_DMA_CFG_DEFAULT                 0x01000000
+#define EIP202_CDR_THRESH_DEFAULT                  0x00000000
+#define EIP202_CDR_COUNT_DEFAULT                   0x00000000
+#define EIP202_CDR_PROC_COUNT_DEFAULT              0x00000000
+#define EIP202_CDR_POINTER_DEFAULT                 0x00000000
+// Ignore the CD FIFO size after reset for this register default value for now
+#define EIP202_CDR_STAT_DEFAULT                    0x00000000
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Read32
+ *
+ * This routine writes to a Register location in the EIP-202 CDR.
+ */
+static inline uint32_t
+EIP202_CDR_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Write32
+ *
+ * This routine writes to a Register location in the EIP-202 CDR.
+ */
+static inline void
+EIP202_CDR_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline void
+EIP202_CDR_STAT_RD(
+        Device_Handle_t Device,
+        bool * const fDMAErrorIrq,
+        bool * const fTreshIrq,
+        bool * const fErrorIrq,
+        bool * const fOuflowIrq,
+        bool * const fTimeoutIrq,
+        uint16_t * const CDFIFOWordCount)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_CDR_Read32(Device, EIP202_CDR_STAT);
+
+    *fDMAErrorIrq      = ((RegVal & BIT_0) != 0);
+    *fTreshIrq         = ((RegVal & BIT_1) != 0);
+    *fErrorIrq         = ((RegVal & BIT_2) != 0);
+    *fOuflowIrq        = ((RegVal & BIT_3) != 0);
+    *fTimeoutIrq       = ((RegVal & BIT_4) != 0);
+    *CDFIFOWordCount   = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_CDR_STAT_FIFO_SIZE_RD(
+        Device_Handle_t Device,
+        uint16_t * const CDFIFOWordCount)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_CDR_Read32(Device, EIP202_CDR_STAT);
+
+    *CDFIFOWordCount   = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_CDR_STAT_CLEAR_ALL_IRQ_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_STAT,
+                       (uint32_t)(EIP202_CDR_STAT_DEFAULT | MASK_5_BITS));
+}
+
+
+static inline void
+EIP202_CDR_RING_BASE_ADDR_LO_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_RING_BASE_ADDR_LO,
+                       EIP202_CDR_RING_BASE_ADDR_LO_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_RING_BASE_ADDR_LO_WR(
+        Device_Handle_t Device,
+        const uint32_t LowAddr)
+{
+    EIP202_CDR_Write32(Device, EIP202_CDR_RING_BASE_ADDR_LO, LowAddr);
+}
+
+
+static inline void
+EIP202_CDR_RING_BASE_ADDR_HI_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_RING_BASE_ADDR_HI,
+                       EIP202_CDR_RING_BASE_ADDR_HI_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_RING_BASE_ADDR_HI_WR(
+        Device_Handle_t Device,
+        const uint32_t HiAddr)
+{
+    EIP202_CDR_Write32(Device, EIP202_CDR_RING_BASE_ADDR_HI, HiAddr);
+}
+
+
+static inline void
+EIP202_CDR_RING_SIZE_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_RING_SIZE,
+                       EIP202_CDR_RING_SIZE_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_RING_SIZE_WR(
+        Device_Handle_t Device,
+        const uint32_t CDRWordCount)
+{
+    uint32_t RegVal = EIP202_CDR_RING_SIZE_DEFAULT;
+
+    RegVal |= ((((uint32_t)CDRWordCount) & MASK_22_BITS) << 2);
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_RING_SIZE, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_DESC_SIZE_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_DESC_SIZE,
+                       EIP202_CDR_DESC_SIZE_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_DESC_SIZE_WR(
+        Device_Handle_t Device,
+        const uint8_t DscrWordCount,
+        const uint8_t DscrOffsWordCount,
+        const bool fATPToToken,
+        const bool fATP,
+        const bool f64bit)
+{
+    uint32_t RegVal = EIP202_CDR_DESC_SIZE_DEFAULT;
+
+    if(f64bit)
+        RegVal |= BIT_31;
+
+    if(fATP)
+        RegVal |= BIT_30;
+
+    if(fATPToToken)
+        RegVal |= BIT_29;
+
+    RegVal |= ((((uint32_t)DscrOffsWordCount) & MASK_8_BITS) << 16);
+    RegVal |= ((((uint32_t)DscrWordCount)     & MASK_8_BITS)      );
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_DESC_SIZE, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_CFG_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_CFG,
+                       EIP202_CDR_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_CFG_WR(
+        Device_Handle_t Device,
+        const uint16_t CDFetchWordCount,
+        const uint16_t CDFetchThreshWordCount)
+{
+    uint32_t RegVal = EIP202_CDR_CFG_DEFAULT;
+
+    RegVal |= ((((uint32_t)CDFetchThreshWordCount) & MASK_10_BITS) << 16);
+    RegVal |= ((((uint32_t)CDFetchWordCount)       & MASK_16_BITS)      );
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_CFG, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_DMA_CFG_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_DMA_CFG,
+                       EIP202_CDR_DMA_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_DMA_CFG_WR(
+        Device_Handle_t Device,
+        const uint8_t CDSwap,
+        const uint8_t DataSwap,
+        const uint8_t TokenSwap,
+        const bool fBuf,
+        const uint8_t WrCache,
+        const uint8_t RdCache,
+        const uint8_t CdProtection,
+        const uint8_t DataProtection,
+        const uint8_t AcdProtection)
+{
+    uint32_t RegVal = EIP202_CDR_DMA_CFG_DEFAULT;
+
+    RegVal &= (~BIT_24);
+    if(fBuf)
+        RegVal |= BIT_24;
+
+    RegVal |= ((((uint32_t)RdCache)   & MASK_3_BITS) << 29);
+    RegVal |= ((((uint32_t)WrCache)   & MASK_3_BITS) << 25);
+    RegVal |= ((((uint32_t)TokenSwap) & MASK_4_BITS) << 16);
+    RegVal |= ((((uint32_t)DataSwap)  & MASK_4_BITS) << 8);
+    RegVal |= ((((uint32_t)CDSwap)    & MASK_4_BITS));
+
+    RegVal |= ((CdProtection & MASK_4_BITS) << 4);
+    RegVal |= ((DataProtection & MASK_4_BITS) << 12);
+    RegVal |= ((AcdProtection  & MASK_4_BITS) << 20);
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_DMA_CFG, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_THRESH_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_THRESH,
+                       EIP202_CDR_THRESH_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_THRESH_WR(
+        Device_Handle_t Device,
+        const uint32_t CDThreshWordCount,
+        const uint8_t CDTimeout)
+{
+    uint32_t RegVal = EIP202_CDR_THRESH_DEFAULT;
+
+    RegVal |= ((((uint32_t)CDTimeout) & MASK_8_BITS) << 24);
+    RegVal |= (CDThreshWordCount            & MASK_22_BITS);
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_THRESH, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_COUNT_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_COUNT,
+                       EIP202_CDR_COUNT_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_COUNT_WR(
+        Device_Handle_t Device,
+        const uint16_t CDCount,
+        const bool fClearCount)
+{
+    uint32_t RegVal = EIP202_CDR_COUNT_DEFAULT;
+
+    if(fClearCount)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)CDCount) & MASK_14_BITS) << 2);
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_COUNT, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_COUNT_RD(
+        Device_Handle_t Device,
+        uint32_t * const CDWordCount_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_CDR_Read32(Device, EIP202_CDR_COUNT);
+
+    *CDWordCount_p   = (uint32_t)((RegVal >> 2) & MASK_22_BITS);
+}
+
+
+static inline void
+EIP202_CDR_PROC_COUNT_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_PROC_COUNT,
+                       EIP202_CDR_PROC_COUNT_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_PROC_COUNT_WR(
+        Device_Handle_t Device,
+        const uint32_t ProcCDWordCount,
+        const uint16_t ProcPktCount,
+        const bool fClearCount)
+{
+    uint32_t RegVal = EIP202_CDR_PROC_COUNT_DEFAULT;
+
+    if(fClearCount)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)ProcCDWordCount) & MASK_22_BITS) << 2);
+    RegVal |= ((((uint32_t)ProcPktCount)    & MASK_7_BITS)  << 24);
+
+    EIP202_CDR_Write32(Device, EIP202_CDR_PROC_COUNT, RegVal);
+}
+
+
+static inline void
+EIP202_CDR_PROC_COUNT_RD(
+        Device_Handle_t Device,
+        uint32_t * const ProcCDWordCount_p,
+        uint8_t * const ProcPktCount_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_CDR_Read32(Device, EIP202_CDR_PROC_COUNT);
+
+    *ProcCDWordCount_p = (uint32_t)((RegVal >> 2)  & MASK_22_BITS);
+    *ProcPktCount_p    = (uint8_t)((RegVal >> 24) & MASK_7_BITS);
+}
+
+
+static inline void
+EIP202_CDR_POINTER_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_POINTER,
+                       EIP202_CDR_POINTER_DEFAULT);
+}
+
+
+static inline void
+EIP202_CDR_POINTER_RD(
+        Device_Handle_t Device,
+        uint32_t * const CDRPointer_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_CDR_Read32(Device, EIP202_CDR_POINTER);
+
+    *CDRPointer_p   = (uint32_t)((RegVal >> 2) & MASK_22_BITS);
+}
+
+static inline bool
+EIP202_CDR_REV_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP202_CDR_SIGNATURE);
+}
+
+
+static inline void
+EIP202_CDR_OPTIONS_RD(
+        Device_Handle_t Device,
+        uint8_t * const NofRings,
+        uint8_t * const NofPes,
+        bool * const fExpPlf,
+        uint8_t * const CF_Size,
+        uint8_t * const RF_Size,
+        uint8_t * const HostIfc,
+        uint8_t * const DMA_Len,
+        uint8_t * const HDW,
+        uint8_t * const TgtAlign,
+        bool * const fAddr64)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP202_CDR_Read32(Device, EIP202_CDR_OPTIONS);
+
+    *fAddr64   = ((RevRegVal & BIT_31) != 0);
+    *TgtAlign  = (uint8_t)((RevRegVal >> 28) & MASK_3_BITS);
+    *HDW       = (uint8_t)((RevRegVal >> 25) & MASK_3_BITS);
+    *DMA_Len   = (uint8_t)((RevRegVal >> 20) & MASK_5_BITS);
+    *HostIfc   = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *fExpPlf   = ((RevRegVal & BIT_15) != 0);
+    // Make RD FIFO size = 2^RF_Size in HDW words
+    *RF_Size   = (uint8_t)((RevRegVal >> 12) & MASK_3_BITS) + 4;
+    // Make CD FIFO size = 2^CF_Size in HDW words
+    *CF_Size   = (uint8_t)((RevRegVal >> 9)  & MASK_3_BITS) + 4;
+    *NofPes    = (uint8_t)((RevRegVal >> 4)  & MASK_5_BITS);
+    *NofRings  = (uint8_t)((RevRegVal)       & MASK_4_BITS);
+}
+
+
+#endif /* EIP202_CDR_LEVEL0_H_ */
+
+
+/* end of file eip202_cdr_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_hw_interface.h
new file mode 100644
index 0000000..cb98b53
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_hw_interface.h
@@ -0,0 +1,172 @@
+/* eip202_global_hw_interface.h
+ *
+ * EIP-202 HIA Global Control HW Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_GLOBAL_HW_INTERFACE_H_
+#define EIP202_GLOBAL_HW_INTERFACE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint16_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP202_DFE_TRD_REG_STAT_IDLE    0xF
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-202 HIA registers
+ *****************************************************************************/
+// EIP-202 HIA EIP number (0xCA) and complement (0x35)
+#define EIP202_SIGNATURE                ((uint16_t)0x35CA)
+
+#define EIP202_REG_OFFS                 4
+
+#define EIP202_FE_REG_MAP_SIZE          128
+
+// HIA Look-aside FIFO base offset
+#define EIP202_LASIDE_BASE              0x9FF00
+#define EIP202_REG_LASIDE_MAP_SIZE      8
+
+// HIA Inline FIFO base offset
+#define EIP202_INLINE_BASE              0x9FF80
+#define EIP202_REG_INLINE_MAP_SIZE      4
+
+// HIA Ring Arbiter map size
+#define EIP202_REG_RA_MAP_SIZE          8
+
+
+// HIA Ring Arbiter
+#define EIP202_RA_REG_PRIO_0     ((EIP202_RA_BASE)+(0x00 * EIP202_REG_OFFS))
+#define EIP202_RA_REG_PRIO_1     ((EIP202_RA_BASE)+(0x01 * EIP202_REG_OFFS))
+#define EIP202_RA_REG_PRIO_2     ((EIP202_RA_BASE)+(0x02 * EIP202_REG_OFFS))
+#define EIP202_RA_REG_PRIO_3     ((EIP202_RA_BASE)+(0x03 * EIP202_REG_OFFS))
+
+// HIA Ring Arbiter control for PE n (n - number of the PE)
+#define EIP202_RA_PE_REG_CTRL(n)   ((EIP202_REG_RA_MAP_SIZE * n) + \
+                                      ((EIP202_RA_BASE) + \
+                                       (0x04 * EIP202_REG_OFFS)))
+
+// HIA DFE all threads
+#define EIP202_DFE_REG_CFG(n)        ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      EIP202_DFE_BASE + \
+                                       (0x00 * EIP202_REG_OFFS))
+
+// HIA DFE thread n (n - number of the DFE thread)
+#define EIP202_DFE_TRD_REG_CTRL(n)   ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      ((EIP202_DFE_TRD_BASE) + \
+                                       (0x00 * EIP202_REG_OFFS)))
+#define EIP202_DFE_TRD_REG_STAT(n)   ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      ((EIP202_DFE_TRD_BASE) + \
+                                       (0x01 * EIP202_REG_OFFS)))
+
+// HIA DSE all threads
+#define EIP202_DSE_REG_CFG(n)        ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      (EIP202_DSE_BASE) + \
+                                       (0x00 * EIP202_REG_OFFS))
+
+// HIA DSE thread n (n - number of the DSE thread)
+#define EIP202_DSE_TRD_REG_CTRL(n)   ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      ((EIP202_DSE_TRD_BASE) + \
+                                       (0x00 * EIP202_REG_OFFS)))
+#define EIP202_DSE_TRD_REG_STAT(n)   ((EIP202_FE_REG_MAP_SIZE * n) + \
+                                      ((EIP202_DSE_TRD_BASE) + \
+                                       (0x01 * EIP202_REG_OFFS)))
+
+
+// HIA Global
+#define EIP202_G_REG_OPTIONS2     ((EIP202_G_BASE)+(0x00 * EIP202_REG_OFFS))
+#define EIP202_G_REG_MST_CTRL     ((EIP202_G_BASE)+(0x01 * EIP202_REG_OFFS))
+#define EIP202_G_REG_OPTIONS      ((EIP202_G_BASE)+(0x02 * EIP202_REG_OFFS))
+#define EIP202_G_REG_VERSION      ((EIP202_G_BASE)+(0x03 * EIP202_REG_OFFS))
+
+// HIA Look-aside (LA) FIFO, k - LA FIFO number, must be from 1 to 5
+#define EIP202_REG_LASIDE_BASE_ADDR_LO      ((EIP202_LASIDE_BASE) + \
+                                                (0x00 * EIP202_REG_OFFS))
+#define EIP202_REG_LASIDE_BASE_ADDR_HI      ((EIP202_LASIDE_BASE) + \
+                                                (0x01 * EIP202_REG_OFFS))
+#define EIP202_REG_LASIDE_SLAVE_CTRL(k)  ((EIP202_REG_LASIDE_MAP_SIZE * k) + \
+                                           ((EIP202_LASIDE_BASE) + \
+                                            (0x00 * EIP202_REG_OFFS)))
+#define EIP202_REG_LASIDE_MASTER_CTRL(k) ((EIP202_REG_LASIDE_MAP_SIZE * k) + \
+                                           ((EIP202_LASIDE_BASE) + \
+                                            (0x01 * EIP202_REG_OFFS)))
+
+// HIA Inline (IN) FIFO base offset, l - IN FIFO number
+#define EIP202_REG_INLINE_CTRL(k)         ((EIP202_REG_INLINE_MAP_SIZE * k) + \
+                                           ((EIP202_INLINE_BASE) + \
+                                            (0x00 * EIP202_REG_OFFS)))
+
+// Default EIP202_DFE_REG_CFG register value
+#define EIP202_DFE_REG_CFG_DEFAULT          0x00000000
+
+// Default EIP202_DFE_TRD_REG_CTRL register value
+#define EIP202_DFE_TRD_REG_CTRL_DEFAULT     0x00000000
+
+// Default EIP202_DSE_REG_CFG register value
+#define EIP202_DSE_REG_CFG_DEFAULT          0x80008000
+
+// Default EIP202_DSE_TRD_REG_CTRL register value
+#define EIP202_DSE_TRD_REG_CTRL_DEFAULT     0x00000000
+
+// Default EIP202_RA_REG_PRIO_x register values
+#define EIP202_RA_REG_PRIO_0_DEFAULT        0x00000000
+#define EIP202_RA_REG_PRIO_1_DEFAULT        0x00000000
+#define EIP202_RA_REG_PRIO_2_DEFAULT        0x00000000
+#define EIP202_RA_REG_PRIO_3_DEFAULT        0x00000000
+#define EIP202_RA_PE_REG_CTRL_DEFAULT       0x00000000
+
+// Default HIA Look-aside (LA) FIFO registers values
+#define EIP202_REG_LASIDE_BASE_ADDR_LO_DEFAULT     0x00000000
+#define EIP202_REG_LASIDE_BASE_ADDR_HI_DEFAULT     0x00000000
+#define EIP202_REG_LASIDE_MASTER_CTRL_DEFAULT      0x00000000
+#define EIP202_REG_LASIDE_SLAVE_CTRL_DEFAULT       0x00000000
+
+// Default HIA Inline (IN) FIFO registers values
+#define EIP202_REG_INLINE_CTRL_DEFAULT             0x00000000
+
+// Default value of the BufferCtrl field in the EIP202_DSE_REG_CFG register
+#define EIP202_DSE_BUFFER_CTRL            ((EIP202_DSE_REG_CFG_DEFAULT >> 14) \
+                                           & MASK_2_BITS)
+
+
+#endif /* EIP202_GLOBAL_HW_INTERFACE_H_ */
+
+
+/* end of file eip202_global_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_init.h
new file mode 100644
index 0000000..0e402ed
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_init.h
@@ -0,0 +1,326 @@
+/* eip202_global_init.h
+ *
+ * EIP-202 Global Init interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_GLOBAL_INIT_H_
+#define EIP202_GLOBAL_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Ring PE assignment map
+typedef struct
+{
+    // PE is selected via the index in the RingPE_Mask array,
+    // index i selects PE i
+    // Bit N:
+    //     0 - ring N is not assigned (cleared) to this PE
+    //     1 - ring N is assigned to this PE
+    uint32_t RingPE_Mask;
+
+    // PE is selected via the index in the RingPrio_Mask array,
+    // index i selects PE i
+    // Bit N:
+    //     0 - ring N is low priority
+    //     1 - ring N is high priority
+    uint32_t RingPrio_Mask;
+
+    // CDR Slots
+    // CDR0: bits 3-0,   CDR1: bits 7-4,   CDR2: bits 11-8,  CDR3: bits 15-12
+    // CDR4: bits 19-16, CDR5: bits 23-20, CDR6: bits 27-24, CDR7: bits 31-28
+    uint32_t RingSlots0;
+
+    // CDR Slots
+    // CDR8:  bits 3-0,   CDR9:  bits 7-4,   CDR10: bits 11-8, CDR11: bits 15-12
+    // CDR12: bits 19-16, CDR13: bits 23-20, CDR14: bits 27-24
+    uint32_t RingSlots1;
+
+} EIP202_Global_Ring_PE_Map_t;
+
+typedef struct
+{
+
+    // Number of statically configured Descriptor Rings
+    uint8_t NofRings;
+
+    // Number of statically configured Processing Engines,
+    // value 0 indicates 8 PEs
+    uint8_t NofPes;
+
+    // If true then 64 bit descriptors will contain a particle
+    // size/fill level extension word to allow particle sizes larger
+    // than 1 MB.
+    bool fExpPlf;
+
+    // Command Descriptor FIFO size, the actual size is 2^CF_Size 32-bit
+    // words.
+    uint8_t CF_Size;
+
+    // Result Descriptor FIFO size, the actual size is 2^RF_Size 32-bit
+    // words.
+    uint8_t RF_Size;
+
+    // Host interface type:
+    // 0 = PLB, 1 = AHB, 2 = TCM, 3 = AXI
+    uint8_t HostIfc;
+
+    // Maximum supported DMA length is 2^(DMA_Len+1) – 1 bytes
+    uint8_t DMA_Len;
+
+    // Host interface data width:
+    // 0 = 32 bits, 1 = 64 bits, 2 = 128 bits, 3 = 256 bits
+    uint8_t HDW;
+
+    // Target access block alignment. If this value is larger than 0,
+    // the distance between 2 rings, 2 AICs and between the DFE and the DSE
+    // in the slave memory map is increased by a factor of 2^TgtAlign.
+    // This means that ring control registers start at 2^(TgtAlign+11) Byte
+    // boundaries (or a 2^(TgtAlign+12) Byte boundary for a combined
+    // CDR/RDR block), the DFE and DSE will start at a 2^(TgtAlign+10) Byte
+    // boundary and AICs will start at 2^(TgtAlign+8) Byte boundaries.
+    uint8_t TgtAlign;
+
+    // 64-bit addressing mode:
+    // false = 32-bit addressing,
+    // true = 64-bit addressing
+    bool fAddr64;
+
+    // Number of statically configured Look-aside interfaces
+    uint8_t NofLA_Ifs;
+
+    // Number of statically configured Inline interfaces
+    uint8_t NofIN_Ifs;
+
+    // AXI master interface only
+    // Number of write channels for a high-performance AXI master interface
+    // minus 1
+    uint8_t NofAXI_WrChs;
+
+    // AXI master interface only
+    // Number of read clusters for a high-performance AXI master interface.
+    uint8_t NofAXI_RdClusters;
+
+    // AXI master interface only
+    // Number of read channels per read cluster for a high-performance AXI
+    // master interface, minus 1
+    uint8_t NofAXI_RdCPC;
+
+    // The basic EIP number.
+    uint8_t EipNumber;
+
+    // The complement of the basic EIP number.
+    uint8_t ComplmtEipNumber;
+
+    // Hardware Patch Level.
+    uint8_t HWPatchLevel;
+
+    // Minor Hardware revision.
+    uint8_t MinHWRevision;
+
+    // Major Hardware revision.
+    uint8_t MajHWRevision;
+
+} EIP202_Capabilities_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * EIP202 Global Functions
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Detect
+ *
+ * Checks the presence of EIP-202 HIA hardware. Returns true when found.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ *
+ * Return value
+ *     true  : Success
+ *     false : Failure
+ */
+bool
+EIP202_Global_Detect(
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Endianness_Slave_Configure
+ *
+ * Configure Endianness Conversion method
+ * for the EIP-202 slave (MMIO) interface
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ *
+ * Return value
+ *     true  : Success
+ *     false : Failure
+ */
+bool
+EIP202_Global_Endianness_Slave_Configure(
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Init
+ *
+ * Initialize the ring, LA-FIFO and inline interfaces of the EIP202 hardware.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ * NofPE (input)
+ *     Number of packet engines in the device.
+ * NofLA (input)
+ *     Number of look-aside FIFOs of the device.
+ * ipbuf_min (input)
+ *     Minimum input packet burst size.
+ * ipbuf_max (input)
+ *     Maximum input packet burst size.
+ * itbuf_min (input)
+ *     Minimum input token burst size.
+ * itbuf_max (input)
+ *     Maximum input token burst size.
+ * opbuf_min (input)
+ *     Minimum output packet burst size.
+ * opbuf_max (input)
+ *     Maximum output packet burst size.
+ */
+void
+EIP202_Global_Init(
+        const Device_Handle_t Device,
+        unsigned int NofPE,
+        unsigned int NofLA,
+        uint8_t ipbuf_min,
+        uint8_t ipbuf_max,
+        uint8_t itbuf_min,
+        uint8_t itbuf_max,
+        uint8_t opbuf_min,
+        uint8_t opbuf_max);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset
+ *
+ * Reset the EIP202 hardware.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ * NofPE (input)
+ *     Number of packet engines in the hardware.
+ *
+ * Return value
+ *     true  : Success
+ *     false : Failure
+ */
+bool
+EIP202_Global_Reset(
+        const Device_Handle_t Device,
+        const unsigned int NofPE);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset_IsDone
+ *
+ * Check if a reset operation (started with EIP202_Global_Reset) is completed
+ * for a specified Packet Engine.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ * PEnr (input)
+ *     Number of the packet engine to check.
+ *
+ * Return value
+ *     true  : Reset is completed
+ *     false : Reset is not completed
+ */
+bool
+EIP202_Global_Reset_IsDone(
+        const Device_Handle_t Device,
+        const unsigned int PEnr);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_HWRevision_Get
+ *
+ * Read hardware revision and capabilities of the EIP202 hardware.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ * Capabilities_p (output)
+ *     Hardware options of the EIP202.
+ */
+void
+EIP202_Global_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP202_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Configure
+ *
+ * Configure the EIP202 for a single Packet Engine.
+ *
+ * Device (input)
+ *     Device handle of the hardware.
+ * PE_Number (input)
+ *     Number of the Packet Engine to configure.
+ * RingPEMap_p (input)
+ *     Structure containing the configuration.
+ */
+void
+EIP202_Global_Configure(
+        const Device_Handle_t Device,
+        const unsigned int PE_Number,
+        const EIP202_Global_Ring_PE_Map_t * const RingPEMap_p);
+
+
+#endif /* EIP202_GLOBAL_INIT_H_ */
+
+
+/* end of file eip202_global_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_level0.h
new file mode 100644
index 0000000..c1e9452
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_global_level0.h
@@ -0,0 +1,953 @@
+/* eip202_global_level0.h
+ *
+ * EIP-202 HIA Global Control Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_GLOBAL_LEVEL0_H_
+#define EIP202_GLOBAL_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// EIP-292 Global Control HW interface
+#include "eip202_global_hw_interface.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+#include "device_swap.h"        // Device_SwapEndian32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Set_Slave_Byte_Order_Swap_Word32
+ *
+ * Helper function that can be used to swap words in the body of the
+ * EIP202_Set_Slave_Byte_Order() functions as well as in the other
+ * functions where words require byte swap before this can be done
+ * by the Packet Engine Slave interface
+  */
+static inline void
+EIP202_Set_Slave_Byte_Order_Swap_Word32(uint32_t* const Word32)
+{
+#ifndef EIP97_GLOBAL_DISABLE_HOST_SWAP_INIT
+
+    uint32_t tmp = Device_SwapEndian32(*Word32);
+
+    *Word32 = tmp;
+
+#else
+    IDENTIFIER_NOT_USED(Word32);
+#endif // !EIP97_GLOBAL_DISABLE_HOST_SWAP_INIT
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202 Global Functions
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP202_Read32
+ *
+ * This routine writes to a Register location in the EIP-202.
+ */
+static inline uint32_t
+EIP202_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Write32
+ *
+ * This routine writes to a Register location in the EIP-202.
+ */
+static inline void
+EIP202_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline bool
+EIP202_REV_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP202_SIGNATURE);
+}
+
+
+static inline void
+EIP202_EIP_REV_RD(
+        Device_Handle_t Device,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP202_OPTIONS_RD(
+        Device_Handle_t Device,
+        uint8_t * const NofRings,
+        uint8_t * const NofPes,
+        bool * const fExpPlf,
+        uint8_t * const CF_Size,
+        uint8_t * const RF_Size,
+        uint8_t * const HostIfc,
+        uint8_t * const DMA_Len,
+        uint8_t * const HDW,
+        uint8_t * const TgtAlign,
+        bool * const fAddr64)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP202_Read32(Device, EIP202_G_REG_OPTIONS);
+
+    *fAddr64   = ((RevRegVal & BIT_31) != 0);
+    *TgtAlign  = (uint8_t)((RevRegVal >> 28) & MASK_3_BITS);
+    *HDW       = (uint8_t)((RevRegVal >> 25) & MASK_3_BITS);
+    *DMA_Len   = (uint8_t)((RevRegVal >> 20) & MASK_5_BITS);
+    *HostIfc   = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *fExpPlf   = ((RevRegVal & BIT_15) != 0);
+    // Make RD FIFO size = 2^RF_Size in HDW words
+    *RF_Size   = (uint8_t)((RevRegVal >> 12) & MASK_3_BITS) + 4;
+    // Make CD FIFO size = 2^CF_Size in HDW words
+    *CF_Size   = (uint8_t)((RevRegVal >> 9)  & MASK_3_BITS) + 4;
+    *NofPes    = (uint8_t)((RevRegVal >> 4)  & MASK_5_BITS);
+    *NofRings  = (uint8_t)((RevRegVal)       & MASK_4_BITS);
+}
+
+
+static inline void
+EIP202_OPTIONS2_RD(
+        Device_Handle_t Device,
+        uint8_t * const NofLA_Ifs,
+        uint8_t * const NofIN_Ifs,
+        uint8_t * const NofAXI_WrChs,
+        uint8_t * const NofAXI_RdClusters,
+        uint8_t * const NofAXI_RdCPC)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP202_Read32(Device, EIP202_G_REG_OPTIONS2);
+
+    *NofAXI_RdCPC      = (uint8_t)((RevRegVal >> 28) & MASK_4_BITS);
+    *NofAXI_RdClusters = (uint8_t)((RevRegVal >> 20) & MASK_8_BITS);
+    *NofAXI_WrChs      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *NofIN_Ifs         = (uint8_t)((RevRegVal >> 4)  & MASK_4_BITS);
+    *NofLA_Ifs         = (uint8_t)((RevRegVal)       & MASK_4_BITS);
+}
+
+
+static inline void
+EIP202_MST_CTRL_BUS_BURST_SIZE_GET(
+        Device_Handle_t Device,
+        uint8_t * const BusBurstSize)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_Read32(Device, EIP202_G_REG_MST_CTRL);
+
+    *BusBurstSize  = (uint8_t)((RegVal >> 4  ) & MASK_4_BITS);
+}
+
+
+static inline void
+EIP202_MST_CTRL_BUS_BURST_SIZE_UPDATE(
+        Device_Handle_t Device,
+        const uint8_t BusBurstSize,
+        const uint8_t RxBusBurstSize)
+{
+    uint32_t RegVal;
+
+    // Preserve other settings
+    RegVal = EIP202_Read32(Device, EIP202_G_REG_MST_CTRL);
+
+    RegVal &= ~MASK_8_BITS;
+
+    RegVal |= (uint32_t)((((uint32_t)BusBurstSize)   & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)RxBusBurstSize) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_G_REG_MST_CTRL, RegVal);
+}
+
+
+static inline void
+EIP202_MST_CTRL_BUS_TIMEOUT_UPDATE(
+        Device_Handle_t Device,
+        const uint8_t Timeout)
+{
+    uint32_t RegVal;
+
+    // Preserve other settings
+    RegVal = EIP202_Read32(Device, EIP202_G_REG_MST_CTRL);
+
+    RegVal &= ~(MASK_6_BITS << 26);
+
+    RegVal |= (uint32_t)((((uint32_t)Timeout) & MASK_6_BITS) << 26);
+
+    EIP202_Write32(Device, EIP202_G_REG_MST_CTRL, RegVal);
+}
+
+
+static inline void
+EIP202_MST_CTRL_BYTE_SWAP_UPDATE(
+        const Device_Handle_t Device,
+        const bool fByteSwap)
+{
+    uint32_t SlaveCfg;
+
+    SlaveCfg = EIP202_Read32(Device, EIP202_G_REG_MST_CTRL);
+
+    // Swap the bytes for the Host endianness format (must be Big Endian)
+    EIP202_Set_Slave_Byte_Order_Swap_Word32(&SlaveCfg);
+
+    // Enable the Slave Endian Byte Swap in HW
+    SlaveCfg &= ~(BIT_25 | BIT_24);
+    SlaveCfg |= (fByteSwap ? BIT_24 : BIT_25);
+
+    // Swap the bytes back for the Device endianness format (Little Endian)
+    EIP202_Set_Slave_Byte_Order_Swap_Word32(&SlaveCfg);
+
+    // Set byte order in the EIP202_G_REG_MST_CTRL register
+    EIP202_Write32(Device, EIP202_G_REG_MST_CTRL, SlaveCfg);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202 Ring Arbiter Functions
+ *
+ */
+
+static inline void
+EIP202_RA_PRIO_0_VALUE32_WR(
+        Device_Handle_t Device,
+        const uint32_t Value)
+{
+    EIP202_Write32(Device, EIP202_RA_REG_PRIO_0, Value);
+}
+
+
+static inline uint32_t
+EIP202_RA_PRIO_0_VALUE32_RD(
+        Device_Handle_t Device)
+{
+    return EIP202_Read32(Device, EIP202_RA_REG_PRIO_0);
+}
+
+
+static inline void
+EIP202_RA_PRIO_0_WR(
+        Device_Handle_t Device,
+        const bool fCDR0High,
+        const uint8_t CDR0_Slots,
+        const bool fCDR1High,
+        const uint8_t CDR1_Slots,
+        const bool fCDR2High,
+        const uint8_t CDR2_Slots,
+        const bool fCDR3High,
+        const uint8_t CDR3_Slots)
+{
+    uint32_t RegVal = EIP202_RA_REG_PRIO_0_DEFAULT;
+
+    if(fCDR0High)
+        RegVal |= BIT_7;
+
+    if(fCDR1High)
+        RegVal |= BIT_15;
+
+    if(fCDR2High)
+        RegVal |= BIT_23;
+
+    if(fCDR3High)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)CDR3_Slots) & MASK_4_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)CDR2_Slots) & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)CDR1_Slots) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)CDR0_Slots) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_RA_REG_PRIO_0, RegVal);
+}
+
+
+static inline void
+EIP202_RA_PRIO_1_WR(
+        Device_Handle_t Device,
+        const bool fCDR4High,
+        const uint8_t CDR4_Slots,
+        const bool fCDR5High,
+        const uint8_t CDR5_Slots,
+        const bool fCDR6High,
+        const uint8_t CDR6_Slots,
+        const bool fCDR7High,
+        const uint8_t CDR7_Slots)
+{
+    uint32_t RegVal = EIP202_RA_REG_PRIO_1_DEFAULT;
+
+    if(fCDR4High)
+        RegVal |= BIT_7;
+
+    if(fCDR5High)
+        RegVal |= BIT_15;
+
+    if(fCDR6High)
+        RegVal |= BIT_23;
+
+    if(fCDR7High)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)CDR7_Slots) & MASK_4_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)CDR6_Slots) & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)CDR5_Slots) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)CDR4_Slots) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_RA_REG_PRIO_1, RegVal);
+}
+
+
+static inline void
+EIP202_RA_PRIO_2_WR(
+        Device_Handle_t Device,
+        const bool fCDR8High,
+        const uint8_t CDR8_Slots,
+        const bool fCDR9High,
+        const uint8_t CDR9_Slots,
+        const bool fCDR10High,
+        const uint8_t CDR10_Slots,
+        const bool fCDR11High,
+        const uint8_t CDR11_Slots)
+{
+    uint32_t RegVal = EIP202_RA_REG_PRIO_2_DEFAULT;
+
+    if(fCDR8High)
+        RegVal |= BIT_7;
+
+    if(fCDR9High)
+        RegVal |= BIT_15;
+
+    if(fCDR10High)
+        RegVal |= BIT_23;
+
+    if(fCDR11High)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)CDR11_Slots) & MASK_4_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)CDR10_Slots) & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)CDR9_Slots)  & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)CDR8_Slots)  & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_RA_REG_PRIO_2, RegVal);
+}
+
+
+static inline void
+EIP202_RA_PRIO_3_WR(
+        Device_Handle_t Device,
+        const bool fCDR12High,
+        const uint8_t CDR12_Slots,
+        const bool fCDR13High,
+        const uint8_t CDR13_Slots,
+        const bool fCDR14High,
+        const uint8_t CDR14_Slots)
+{
+    uint32_t RegVal = EIP202_RA_REG_PRIO_3_DEFAULT;
+
+    if(fCDR12High)
+        RegVal |= BIT_7;
+
+    if(fCDR13High)
+        RegVal |= BIT_15;
+
+    if(fCDR14High)
+        RegVal |= BIT_23;
+
+    RegVal |= (uint32_t)((((uint32_t)CDR14_Slots) & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)CDR13_Slots) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)CDR12_Slots) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_RA_REG_PRIO_3, RegVal);
+}
+
+
+static inline void
+EIP202_RA_PRIO_0_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_RA_REG_PRIO_0,
+                   EIP202_RA_REG_PRIO_0_DEFAULT);
+}
+
+
+static inline void
+EIP202_RA_PRIO_1_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_RA_REG_PRIO_1,
+                   EIP202_RA_REG_PRIO_1_DEFAULT);
+}
+
+
+static inline void
+EIP202_RA_PRIO_2_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_RA_REG_PRIO_2,
+                   EIP202_RA_REG_PRIO_2_DEFAULT);
+}
+
+
+static inline void
+EIP202_RA_PRIO_3_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_RA_REG_PRIO_3,
+                   EIP202_RA_REG_PRIO_3_DEFAULT);
+}
+
+static inline void
+EIP202_RA_PE_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_RA_PE_REG_CTRL(PEnr),
+                   EIP202_RA_PE_REG_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_RA_PE_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint16_t RingPEmap,
+        const bool fEnable,
+        const bool fReset)
+{
+    uint32_t RegVal = EIP202_RA_PE_REG_CTRL_DEFAULT;
+
+    if(RingPEmap > 0)
+        RegVal |= (((uint32_t)RingPEmap) & MASK_15_BITS);
+
+    if(fEnable)
+        RegVal |= BIT_30;
+
+    if(fReset)
+        RegVal |= BIT_31;
+
+    EIP202_Write32(Device, EIP202_RA_PE_REG_CTRL(PEnr), RegVal);
+}
+/*----------------------------------------------------------------------------
+ * EIP202 DFE Thread Functions
+ *
+ */
+
+static inline void
+EIP202_DFE_CFG_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_DFE_REG_CFG(PEnr) + Offset,
+                   EIP202_DFE_REG_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_DFE_CFG_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint8_t MinDataSize,
+        const uint8_t DataCacheCtrl,
+        const uint8_t MaxDataSize,
+        const uint8_t MinCtrlSize,
+        const uint8_t CtrlCacheCtrl,
+        const uint8_t MaxCtrlSize,
+        const bool fAdvThreshMode,
+        const bool fAggressive)
+{
+    uint32_t RegVal = EIP202_DFE_REG_CFG_DEFAULT;
+
+    if(fAggressive)
+        RegVal |= BIT_31;
+
+    if(fAdvThreshMode)
+        RegVal |= BIT_29;
+
+    RegVal |= (uint32_t)((((uint32_t)MaxCtrlSize)   & MASK_4_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)CtrlCacheCtrl) & MASK_3_BITS) << 20);
+    RegVal |= (uint32_t)((((uint32_t)MinCtrlSize)   & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)MaxDataSize)   & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)DataCacheCtrl) & MASK_3_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)MinDataSize)   & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_DFE_REG_CFG(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DFE_TRD_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_DFE_TRD_REG_CTRL(PEnr) + Offset,
+                   EIP202_DFE_TRD_REG_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_DFE_TRD_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint16_t RingPEmap,
+        const bool fEnable,
+        const bool fReset)
+{
+    uint32_t RegVal = EIP202_DFE_TRD_REG_CTRL_DEFAULT;
+
+    IDENTIFIER_NOT_USED(RingPEmap);
+    IDENTIFIER_NOT_USED(fEnable);
+    if(fReset)
+        RegVal |= BIT_31;
+
+    EIP202_Write32(Device, EIP202_DFE_TRD_REG_CTRL(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DFE_TRD_CTRL_UPDATE(
+        const Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint16_t RingPEmap,
+        const bool fEnable,
+        const bool fReset)
+{
+    uint32_t RegVal;
+
+    // Preserve other settings
+    RegVal = EIP202_Read32(Device, EIP202_DFE_TRD_REG_CTRL(PEnr) + Offset);
+
+    RegVal &= (~MASK_15_BITS);
+    RegVal |= (((uint32_t)RingPEmap) & MASK_15_BITS);
+
+    if(fEnable)
+        RegVal |= BIT_30;
+    else
+        RegVal &= (~BIT_30);
+
+    if(fReset)
+        RegVal |= BIT_31;
+    else
+        RegVal &= (~BIT_31);
+
+    EIP202_Write32(Device, EIP202_DFE_TRD_REG_CTRL(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DFE_TRD_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        uint16_t * const CDFIFOWordCount,
+        uint8_t * const CDRId,
+        uint16_t * const DMAByteCount,
+        bool * const fTokenDMABusy,
+        bool * const fDataDMABusy,
+        bool * const fDMAError)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_Read32(Device, EIP202_DFE_TRD_REG_STAT(PEnr) + Offset);
+
+    *fDMAError         = ((RegVal & BIT_31) != 0);
+    *fDataDMABusy      = ((RegVal & BIT_29) != 0);
+    *fTokenDMABusy     = ((RegVal & BIT_28) != 0);
+    *DMAByteCount      = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+    *CDRId             =  (uint8_t)((RegVal >> 12) & MASK_4_BITS);
+    *CDFIFOWordCount   = (uint16_t)((RegVal)       & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_DFE_TRD_STAT_RINGID_RD(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        uint8_t * const CDRId)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_Read32(Device, EIP202_DFE_TRD_REG_STAT(PEnr) + Offset);
+
+    *CDRId  = (uint8_t)((RegVal >> 12) & MASK_4_BITS);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202 DSE Thread Functions
+ *
+ */
+
+static inline void
+EIP202_DSE_CFG_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_DSE_REG_CFG(PEnr) + Offset,
+                   EIP202_DSE_REG_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_DSE_CFG_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint8_t MinDataSize,
+        const uint8_t DataCacheCtrl,
+        const uint8_t MaxDataSize,
+        const uint8_t BufferCtrl,
+        const bool fEnableSingleWr,
+        const bool fAggressive)
+{
+    uint32_t RegVal = EIP202_DSE_REG_CFG_DEFAULT;
+
+    RegVal &= (~BIT_31);
+    if(fAggressive)
+        RegVal |= BIT_31;
+
+    if(fEnableSingleWr)
+        RegVal |= BIT_29;
+
+    RegVal &= (uint32_t)(~(MASK_2_BITS << 14)); // Clear BufferCtrl field
+    RegVal |= (uint32_t)((((uint32_t)BufferCtrl)    & MASK_2_BITS) << 14);
+    RegVal |= (uint32_t)((((uint32_t)MaxDataSize)   & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)DataCacheCtrl) & MASK_3_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)MinDataSize)   & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_DSE_REG_CFG(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DSE_TRD_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_DSE_TRD_REG_CTRL(PEnr) + Offset,
+                   EIP202_DSE_TRD_REG_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_DSE_TRD_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint16_t RingPEmap,
+        const bool fEnable,
+        const bool fReset)
+{
+    uint32_t RegVal = EIP202_DSE_TRD_REG_CTRL_DEFAULT;
+    IDENTIFIER_NOT_USED(RingPEmap);
+
+    if(fEnable)
+        RegVal |= BIT_30;
+
+    if(fReset)
+        RegVal |= BIT_31;
+
+    EIP202_Write32(Device, EIP202_DSE_TRD_REG_CTRL(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DSE_TRD_CTRL_UPDATE(
+        const Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        const uint16_t RingPEmap,
+        const bool fEnable,
+        const bool fReset)
+{
+    uint32_t RegVal;
+
+    // Preserve other settings
+    RegVal = EIP202_Read32(Device, EIP202_DSE_TRD_REG_CTRL(PEnr) + Offset);
+
+    RegVal &= (~MASK_15_BITS);
+    RegVal |= (((uint32_t)RingPEmap) & MASK_15_BITS);
+
+    if(fEnable)
+        RegVal |= BIT_30;
+    else
+        RegVal &= (~BIT_30);
+
+    if(fReset)
+        RegVal |= BIT_31;
+    else
+        RegVal &= (~BIT_31);
+
+    EIP202_Write32(Device, EIP202_DSE_TRD_REG_CTRL(PEnr) + Offset, RegVal);
+}
+
+
+static inline void
+EIP202_DSE_TRD_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        uint16_t * const RDFIFOWordCount,
+        uint8_t * const RDRId,
+        uint16_t * const DMAByteCount,
+        bool * const fDataFlushBusy,
+        bool * const fDataDMABusy,
+        bool * const fDMAError)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_Read32(Device, EIP202_DSE_TRD_REG_STAT(PEnr) + Offset);
+
+    *fDMAError         = ((RegVal & BIT_31) != 0);
+    *fDataDMABusy      = ((RegVal & BIT_29) != 0);
+    *fDataFlushBusy    = ((RegVal & BIT_28) != 0);
+    *DMAByteCount      = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+    *RDRId             =  (uint8_t)((RegVal >> 12) & MASK_4_BITS);
+    *RDFIFOWordCount   = (uint16_t)((RegVal)       & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_DSE_TRD_STAT_RINGID_RD(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const unsigned int PEnr,
+        uint8_t * const CDRId)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_Read32(Device, EIP202_DSE_TRD_REG_STAT(PEnr) + Offset);
+
+    *CDRId = (uint8_t)((RegVal >> 12) & MASK_4_BITS);
+}
+
+
+static inline void
+EIP202_LASIDE_BASE_ADDR_LO_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_REG_LASIDE_BASE_ADDR_LO,
+                   EIP202_REG_LASIDE_BASE_ADDR_LO_DEFAULT);
+}
+
+
+static inline void
+EIP202_LASIDE_BASE_ADDR_LO_WR(
+        Device_Handle_t Device,
+        const uint8_t DscrDataSwap)
+{
+    uint32_t RegVal = EIP202_REG_LASIDE_BASE_ADDR_LO_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)DscrDataSwap)   & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_REG_LASIDE_BASE_ADDR_LO, RegVal);
+}
+
+
+static inline void
+EIP202_LASIDE_BASE_ADDR_HI_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_Write32(Device,
+                   EIP202_REG_LASIDE_BASE_ADDR_HI,
+                   EIP202_REG_LASIDE_BASE_ADDR_HI_DEFAULT);
+}
+
+
+static inline void
+EIP202_LASIDE_SLAVE_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_REG_LASIDE_SLAVE_CTRL(FIFOnr),
+                   EIP202_REG_LASIDE_SLAVE_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_LASIDE_SLAVE_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr,
+        const uint8_t InPktDataSwap,
+        const uint8_t PktProt,
+        const uint8_t TokenDataSwap,
+        const uint8_t TokenProt,
+        const bool fDscrErrorClear)
+{
+    uint32_t RegVal = EIP202_REG_LASIDE_SLAVE_CTRL_DEFAULT;
+
+    if(fDscrErrorClear)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)TokenProt)     & MASK_4_BITS) << 12);
+    RegVal |= (uint32_t)((((uint32_t)TokenDataSwap) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)PktProt)       & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)InPktDataSwap) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_REG_LASIDE_SLAVE_CTRL(FIFOnr), RegVal);
+}
+
+
+static inline void
+EIP202_LASIDE_MASTER_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_REG_LASIDE_MASTER_CTRL(FIFOnr),
+                   EIP202_REG_LASIDE_MASTER_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_LASIDE_MASTER_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr,
+        const uint8_t OutPktDataSwap,
+        const uint8_t PktProt,
+        const bool fDscrErrorClear)
+{
+    uint32_t RegVal = EIP202_REG_LASIDE_MASTER_CTRL_DEFAULT;
+
+    if(fDscrErrorClear)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)PktProt)        & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)OutPktDataSwap) & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_REG_LASIDE_MASTER_CTRL(FIFOnr), RegVal);
+}
+
+
+static inline void
+EIP202_INLINE_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr)
+{
+    EIP202_Write32(Device,
+                   EIP202_REG_INLINE_CTRL(FIFOnr),
+                   EIP202_REG_INLINE_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP202_INLINE_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int FIFOnr,
+        const uint8_t InPktDataSwap,
+        const bool fInProtoErrorClear,
+        const uint8_t OutPktDataSwap,
+        const uint8_t ThreshLo,
+        const uint8_t ThreshHi,
+        const uint8_t BurstSize,
+        const bool fForceInOrder)
+{
+    uint32_t RegVal = EIP202_REG_INLINE_CTRL_DEFAULT;
+
+    if(fInProtoErrorClear)
+        RegVal |= BIT_7;
+
+    if(fForceInOrder)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)BurstSize)      & MASK_4_BITS) << 20);
+    RegVal |= (uint32_t)((((uint32_t)ThreshHi)       & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)ThreshLo)       & MASK_4_BITS) << 12);
+    RegVal |= (uint32_t)((((uint32_t)OutPktDataSwap) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)InPktDataSwap)  & MASK_4_BITS));
+
+    EIP202_Write32(Device, EIP202_REG_INLINE_CTRL(FIFOnr), RegVal);
+}
+
+#endif /* EIP202_GLOBAL_LEVEL0_H_ */
+
+
+/* end of file eip202_global_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rd_format.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rd_format.h
new file mode 100644
index 0000000..ea51f1b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rd_format.h
@@ -0,0 +1,160 @@
+/* eip202_rd_format.h
+ *
+ * EIP-202 Ring Control Driver Library API Result Descriptor Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RD_FORMAT_H_
+#define EIP202_RD_FORMAT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_rdr.h"                // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"              // DMAResource_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Make_ControlWord
+ *
+ * This helper function returns the Control Word that can be written to
+ * the EIP-202 Prepared Descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_RD_Make_ControlWord(
+        const uint8_t ExpectedResultWordCount,
+        const uint32_t PrepSegmentByteCount,
+        const bool fFirstSegment,
+        const bool fLastSegment);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Prepared_Write
+ *
+ * This helper function writes the EIP-202 Logical Prepared Descriptor to the RDR
+ *
+ * This function is not re-entrant.
+ *
+ */
+void
+EIP202_Prepared_Write(
+        DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const EIP202_ARM_PreparedDescriptor_t * const Descr_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ReadDescriptor
+ *
+ * This helper function reads the EIP-202 Result Descriptor from the RDR
+ *
+ * This function is not re-entrant.
+ *
+ */
+void
+EIP202_ReadDescriptor(
+        EIP202_ARM_ResultDescriptor_t * const Descr_p,
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const unsigned int DescOffsetWordCount,
+        const unsigned int TokenOffsWordCount,
+        bool * const fLastSegment,
+        bool * const fFirstSegment);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ClearDescriptor
+ *
+ * This helper function clears the EIP-202 Result Descriptor in the RDR
+ *
+ * This function is not re-entrant.
+ *
+ */
+void
+EIP202_ClearDescriptor(
+        EIP202_ARM_ResultDescriptor_t * const Descr_p,
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const unsigned int TokenOffsWordCount,
+        const unsigned int DscrWordCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_ControlWord
+ *
+ * This helper function reads the EIP-202 Result Descriptor Control Word
+ * and Result Token Data
+ *
+ * This function is not re-entrant.
+ *
+ */
+void
+EIP202_RD_Read_ControlWord(
+        const uint32_t ControlWord,
+        uint32_t * TokenData_pp,
+        EIP202_RDR_Result_Control_t * const RDControl_p,
+        EIP202_RDR_Result_Token_t * const ResToken_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_BypassData
+ */
+void
+EIP202_RD_Read_BypassData(
+        const uint32_t * BypassData_p,
+        const uint8_t BypassWordCount,
+        EIP202_RDR_BypassData_t * const BD_p);
+
+
+#endif /* EIP202_RD_FORMAT_H_ */
+
+
+/* end of file eip202_rd_format.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr.h
new file mode 100644
index 0000000..f318be6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr.h
@@ -0,0 +1,837 @@
+/* eip202_rdr.h
+ *
+ * EIP-202 Driver Library API:
+ * Result Descriptor Ring (RDR)
+ *
+ * All the RDR API functions can be used concurrently with the CDR API functions
+ * for any ring interface ID unless the API function description states
+ * otherwise.
+ *
+ * Refer to the EIP-202 Driver Library User Guide for more information about
+ * usage of this API
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RDR_H_
+#define EIP202_RDR_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+// EIP-202 Ring Control Driver Library Common Types API
+#include "eip202_ring_types.h"       // EIP202_* common types
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Processed result descriptor Control Data size (in 32-bit words)
+
+#ifdef EIP202_64BIT_DEVICE
+#define EIP202_RD_CTRL_DATA_MAX_WORD_COUNT  4
+#else
+#define EIP202_RD_CTRL_DATA_MAX_WORD_COUNT  2
+#endif // !EIP202_64BIT_DEVICE
+
+// RDR Status information
+typedef struct
+{
+    // Fatal errors (interrupts), set to true when pending
+    // RDR must be re-initialized in case of a fatal error
+    bool        fDMAError;
+    bool        fError;
+    bool        fOUFlowError;
+
+    // Result Descriptor Buffer Overflow Interrupt (not fatal),
+    // set to true when pending
+    bool        fRDBufOverflowInt;
+
+    // Result Descriptor Overflow Interrupt (not fatal),
+    // set to true when pending
+    bool        fRDOverflowInt;
+
+   /* The Buffer/Descriptor Overflow interrupts are not fatal errors and do
+    * not require the reset. These events signal that packet or result
+    * descriptor data  is lost. In this situation the packet processing result
+    * must be discarded by the Host. These events when occur are also signaled
+    * via the result descriptor bits.
+    */
+
+    // Threshold Interrupt (not fatal), set to true when pending
+    bool        fTresholdInt;
+
+    // Timeout Interrupt (not fatal), set to true when pending
+    bool        fTimeoutInt;
+
+    // Number of 32-bit words that are currently free
+    // in the Result Descriptor FIFO
+    uint16_t    RDFIFOWordCount;
+
+    // Number of 32-bit words that are prepared in the RDR
+    uint32_t    RDPrepWordCount;
+
+    // Number of 32-bit words that are processed and stored in the RDR
+    uint32_t    RDProcWordCount;
+
+    // Number of full packets (i.e. the amount of
+    // descriptors marked Last_Seg written) written to the RDR
+    // (i.e. ‘processed’ / ‘updated’) and not yet acknowledged (processed)
+    // by the host.
+    uint8_t     RDProcPktWordCount;
+} EIP202_RDR_Status_t;
+
+// RDR settings
+typedef struct
+{
+    // Other ARM settings
+    EIP202_ARM_Ring_Settings_t   Params;
+
+    // Make settings specific for continuous scatter mode.
+    bool fContinuousScatter;
+} EIP202_RDR_Settings_t;
+
+// Control word parameters for the Logical Prepared Descriptor
+typedef struct
+{
+    // Set to true for the first descriptor in the descriptor chain
+    bool        fFirstSegment;
+
+    // Set to true for the last descriptor in the descriptor chain
+    bool        fLastSegment;
+
+    // Prepared segment size in bytes
+    uint32_t    PrepSegmentByteCount;
+
+    // Expected result token data size in 32-bit words, optional
+    uint32_t    ExpectedResultWordCount;
+
+} EIP202_RDR_Prepared_Control_t;
+
+// Logical Prepared Descriptor
+typedef struct
+{
+    // Control word for the prepared descriptor
+    // EIP202_RDR_Write_Prepared_ControlWord() helper function
+    // can be used for obtaining this word
+    uint32_t                PrepControlWord;
+
+    // Destination packet data buffer, has to be provided by the caller:
+    // Physical address that can be used by Device DMA
+    EIP202_DeviceAddress_t   DstPacketAddr;
+
+} EIP202_ARM_PreparedDescriptor_t;
+
+// Control word parameters for the Logical Result Descriptor
+typedef struct
+{
+    // Set to true for the first descriptor in the descriptor chain
+    bool        fFirstSegment;
+
+    // Set to true for the last descriptor in the descriptor chain
+    bool        fLastSegment;
+
+    // Set to true when the output data does not fit in the last output segment
+    // assigned to this packet
+    bool        fBufferOverflow;
+
+    // Set to true when the result data does not fit the result descriptor
+    bool        fDscrOverflow;
+
+    // Actual processed segment size in bytes
+    uint32_t    ProcSegmentByteCount;
+
+    // Actual processed result token data size in 32-bit words,
+    // for the last segment only
+    uint32_t    ProcResultWordCount;
+
+} EIP202_RDR_Result_Control_t;
+
+// Result Token Data data structure embedded into processed result descriptors
+typedef struct
+{
+    // PE specific error code
+    uint32_t    ErrorCode;
+
+    // Result packet size,
+    // sum of all actual segment sizes that belong to this packet
+    uint32_t    PacketByteCount;
+
+    uint8_t     NextHeader;
+    uint8_t     HashByteCount;
+    uint8_t     BypassWordCount;  // in 32-bit words
+    uint8_t     PadByteCount;
+    bool        fE15;             // true when E15 occurred
+    bool        fHash;            // true when hash "HashByteCount" bytes are
+                                  // appended at the end of packet data
+    uint8_t     BCNL;             // BCNL mask in bits 0 (B) - 3 (L)
+
+    // This parameter is copied through from command to result descriptor
+    // unless EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS configuration parameter
+    // is defined in c_eip202_ring.h
+    uint32_t    ApplicationId;
+
+    // Bypass token words received from the PE
+    // Optional, up to 3 32-bit words, actual length is in "BypassWordCount"
+    uint32_t*   BypassData_p;
+
+} EIP202_RDR_Result_Token_t;
+
+// Bypass Data for successful packet processing
+typedef struct
+{
+    // Type of Service / Traffic class
+    uint8_t TOS_TC;
+
+    // Don't fragment flag
+    bool fDF;
+
+    // Next Header field offset within IPv6 packet header header
+    uint16_t NextHeaderOffset;
+
+    // Application-specific reference to the Header Processing Context
+    uint32_t HdrProcCtxRef;
+
+} EIP202_RDR_BypassData_Pass_t;
+
+// Bypass Data for failed packet processing
+typedef struct
+{
+    // See EIP202_RDR_BYPASS_FLAG_*
+    uint8_t ErrorFlags;
+
+} EIP202_RDR_BypassData_Fail_t;
+
+// Bypass data
+typedef union
+{
+    // Use when BypassWordCount = 2 in Result Token
+    EIP202_RDR_BypassData_Pass_t Pass;
+
+    // Use when BypassWordCount = 1 in Result Token
+    EIP202_RDR_BypassData_Fail_t Fail;
+
+} EIP202_RDR_BypassData_t;
+
+// Logical Result Descriptor
+typedef struct
+{
+    // control fields for the command descriptor
+    // EIP202_RDR_Read_Processed_ControlWord() helper function
+    // can be used for obtaining this word
+    uint32_t ProcControlWord;
+
+    // Destination packet (segment) data, has to be provided by the caller:
+    // Physical address that can be used by Device DMA
+    EIP202_DeviceAddress_t DstPacketAddr;
+
+    // control fields for the command descriptor
+    // EIP202_RDR_Read_Processed_ControlWord() helper function
+    // can be used for obtaining this word
+
+    // Output Token buffer with fixed size
+    uint32_t * Token_p;
+
+} EIP202_ARM_ResultDescriptor_t;
+
+
+/*----------------------------------------------------------------------------
+ * RDR Initialization API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Init
+ *
+ * This function performs the initialization of the EIP-202 RDR
+ * interface and transits the API to the Initialized state.
+ *
+ * This function returns the EIP202_RING_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Ring Control Driver Library configuration.
+ *
+ * Note: This function must be called either after the EIP-202 HW Reset or
+ *       after the Ring SW Reset, see the EIP202_RDR_Reset() function.
+ *       This function as well as optionally EIP202_RDR_Reset() function must be
+ *       executed before any other of the EIP202_RDR_*() functions can be called.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_RDR_Reset() function for the same Device.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the RDR instance.
+ *
+ * Device (input)
+ *     Handle for the Ring Control device instance returned by Device_Find()
+ *     for this RDR instance.
+ *
+ * RingSettings_p (input)
+ *     Pointer to the data structure that contains RDR configuration parameters
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Init(
+        EIP202_Ring_IOArea_t * IOArea_p,
+        const Device_Handle_t Device,
+        const EIP202_RDR_Settings_t * const RingSettings_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Reset
+ *
+ * This function performs the RDR SW Reset and transits the API
+ * to the Uninitialized state. This function must be called before using
+ * the other RDR API functions if the state of the ring is Unknown.
+ *
+ * This function can be used to recover the RDR from a fatal error.
+ *
+ * Note: This function must be called before calling the EIP202_RDR_Init()
+ *       function only if the EIP-202 HW Reset was not done. Otherwise it still
+ *       is can be called but it is not necessary.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_RDR_Init() function for the same Device.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the RDR instance identified by the Device parameter.
+ *
+ * Device (input)
+ *     Handle for the Ring Control device instance returned by Device_Find
+ *     for this RDR instance.
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Reset(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * RDR Descriptor I/O API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_FillLevel_Get
+ *
+ * This function outputs the fill level of the RDR for all the descriptors
+ * requested by means of the RingID parameter. The fill level is obtained as
+ * a number of prepared  (via EIP202_RDR_Descriptor_Prepare) and processed result
+ * descriptors that are NOT obtained (via EIP202_RDR_Descriptor_Get)
+ * by the Host yet.
+ *
+ * The RDR states such as "Ring Full", "Ring Empty" and "Ring Free" are not
+ * changed by this function, e.g. it does not perform any state transition.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_RDR_Descriptor_Prepare() function for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of prepared
+ *     descriptors pending in the RDR will be stored
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Prepared_FillLevel_Get
+ *
+ * This function outputs the fill level of the RDR for the Prepared Descriptors
+ * requested by means of the RingID parameter. The fill level is obtained as
+ * a number of prepared descriptors that have been submitted to the RDR but
+ * not processed by the device yet.
+ *
+ * The RDR states such as "Ring Full", "Ring Empty" and "Ring Free" are not
+ * changed by this function, e.g. it does not perform any state transition.
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_RDR_Descriptor_Prepare() function for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of prepared
+ *     descriptors pending in the RDR will be stored
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Prepared_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Write_Prepared_ControlWord
+ *
+ * This helper function returns the control word that can be written to
+ * the logical prepared descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_RDR_Write_Prepared_ControlWord(
+        const EIP202_RDR_Prepared_Control_t * const  PreparedCtrl_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Prepare
+ *
+ * This function prepares a requested number of descriptors to the RDR.
+ * The function returns EIP202_RING_NO_ERROR and zero descriptors done count
+ * (*DscrDoneCount_p set to 0) when no descriptors can be added to the RDR.
+ * Until prepared descriptors are submitted to the RDR no result descriptors
+ * can be retrieved from it. The prepared descriptors must refer to the Packet
+ * Data DMA buffers that are large enough to receive the processed by the PE
+ * data submitted via the CDR (see the EIP-202 Ring Control CDR API).
+ *
+ * The RDR states such as "Ring Full", "Ring Empty" and "Ring Free" are not
+ * changed by this function, e.g. it does not perform any state transition.
+ *
+ * This function can be called after
+ * the EIP202_RDR_FillLevel_Get() function when the latter checks
+ * how many descriptors can be added to the RDR.
+ *
+ * The execution context calling this API must
+ *
+ * 1) Provide input data via the RDR using the EIP202_RDR_Descriptor_Prepare()
+ * function before it or another context can obtain output data from the RDR.
+ * This requirement is relevant for the look-aside and in-line use case only.
+ *
+ * 2) Ensure that Packet Data DMA buffers referred to by the prepared
+ * descriptors are not re-used or freed by it or another context until
+ * the processed result descriptor(s) referring to the packet associated with
+ * these buffers is(are) fully processed by the Device. This is required not
+ * only when in-place packet transform is done using the same Packet Data DMA
+ * buffer as input and output buffer but also when different DMA buffers are
+ * used for the packet processing input and output data.
+ *
+ * 3) Keep the packet descriptor chain state consistent. All descriptors that
+ * belong to the same packet must be submitted atomically into the RDR without
+ * being intermixed with descriptors that belong to other packets.
+ *
+ * 4) Submit the descriptors that belong to the same packet descriptor chain in
+ * the right order, e.g. first descriptor for the first segment followed by
+ * the middle descriptors followed by the last descriptor.
+ *
+ * 5) Ensure it does not call this function concurrently with another context
+ * for the same RingID.
+ *
+ * 6) Ensure it does not call this function concurrently with another context
+ * calling the EIP202_RDR_Prepared_FillLevel_Get() and
+ * EIP202_RDR_FillLevel_Get() functions for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * PreparedDscr_p (input)
+ *     Pointer to 1st in the the array of prepared descriptors.
+ *
+ * DscrRequestedCount (input)
+ *     Number of prepared descriptors stored back-to-back in the array
+ *     pointed to by PreparedDscr_p.
+ *
+ * DscrPreparedCount_p (output)
+ *     Pointer to the memory location where the number of prepared descriptors
+ *     actually added to the RDR will be stored.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of prepared
+ *     descriptors pending in the RDR will be stored
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : feature is not supported
+ *     EIP202_RING_ARGUMENT_ERROR : passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Prepare(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const EIP202_ARM_PreparedDescriptor_t * PreparedDscr_p,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrPreparedCount_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_Get
+ *
+ * This function outputs the fill level of the ring requested by means of
+ * the RingID parameter. The fill level is obtained as a number of result
+ * descriptors that have been processed by the Device but not processed
+ * by the Host yet.
+ *
+ * When the RDR is in the "Ring Full" state this function outputs the fill
+ * level equal to the RDR size. When the RDR is in the "Ring Empty" state this
+ * functions outputs the zero fill level. the RDR is in the "Ring Free" state
+ * when this function returns the fill level that is greater than zero and less
+ * than the RDR size (in result descriptors).
+ *
+ * This function cannot be called concurrently with
+ * the EIP202_RDR_Descriptor_Get() function for the same Device.
+ *
+ * Note: This function returns EIP202_RING_UNSUPPORTED_FEATURE_ERROR
+ *       when the EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS parameter is
+ *       set.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of processed result
+ *     descriptors pending in the RDR will be stored
+ *     RDR Empty: FillLevel = 0
+ *     RDR Free:  0 < FillLevel < RingSize (in descriptors)
+ *     RDR Full:  FillLevel = RingSize (in descriptors)
+ *
+ * FillLevelPktCount_p (output)
+ *     Pointer to the memory location where the number of processed result
+ *     packets (whose descriptors are pending in the RDR) will be stored.
+ *     In case this parameter outputs 127 then there can be more packets
+ *     available.
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : feature is not supported
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p,
+        unsigned int * FillLevelPktCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_ControlWord
+ *
+ * This helper function outputs the control word that can be read from
+ * the logical processed result descriptor.
+ *
+ * ResDscr_p (input)
+ *     Processed result descriptor with the control information and
+ *     token result data must be read from.
+ *
+ * RDControl_p (output)
+ *     Pointer to the data structure where the result descriptor control
+ *     information will be written.
+ *
+ * ResToken_p (output)
+ *     Pointer to the data structure where the result token
+ *     information will be written.
+ *
+ * This function is re-entrant.
+ *
+ */
+void
+EIP202_RDR_Read_Processed_ControlWord(
+        EIP202_ARM_ResultDescriptor_t * const  ResDscr_p,
+        EIP202_RDR_Result_Control_t * const RDControl_p,
+        EIP202_RDR_Result_Token_t * const ResToken_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_BypassData
+ *
+ * This helper function outputs the bypass data that can be read from
+ * the result token data of the logical processed result descriptor.
+ *
+ * ResToken_p (input)
+ *     Pointer to the data structure where the result token
+ *     information will be written.
+ *
+ * BD_p (output)
+ *     Pointer to the data structure where the bypass data
+ *     information will be written.
+ *
+ * This function is re-entrant.
+ */
+void
+EIP202_RDR_Read_Processed_BypassData(
+        const EIP202_RDR_Result_Token_t * const  ResToken_p,
+        EIP202_RDR_BypassData_t * const BD_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Get
+ *
+ * This function gets a requested number of result descriptors from the RDR.
+ * The function returns EIP202_RING_NO_ERROR and zero descriptors done count
+ * (*DscrDoneCount_p set to 0) when no descriptors can be retrieved from
+ * the RDR, e.g. "Ring Empty" state.
+ *
+ * This function can be used together with
+ * the EIP202_RDR_Processed_FillLevel_Get() function when the latter checks
+ * how many command descriptors can be retrieved from the RDR.
+ *
+ * The execution context calling this API function must
+ *
+ * 1) Ensure it does not call this function concurrently with another context
+ * for the same Device;
+ *
+ * 2) Ensure it does not call this function concurrently with another context
+ * calling the EIP202_RDR_Processed_FillLevel_Get() function for the same Device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * ResultDscr_p (input)
+ *     Pointer to 1st in the the array of command descriptors.
+ *
+ * PktRequestedCount (input)
+ *     Maximum number of packet descriptor chains which result descriptors
+ *     should be obtained by this function. This function will obtain
+ *     the result descriptors for the fully processed packet chains only.
+ *     If set to 0 then this function will try to obtain no more result
+ *     descriptors than specified by the DscrRequestedCount parameter.
+ *
+ * DscrRequestedCount (input)
+ *     Number of descriptors stored back-to-back in the array
+ *     pointed to by ResultDscr_p. Cannot be zero.
+ *
+ * DscrDoneCount_p (output)
+ *     Pointer to the memory location where the number of descriptors
+ *     actually added to the RDR will be stored.
+ *
+ * FillLevelDscrCount_p (output)
+ *     Pointer to the memory location where the number of processed result
+ *     descriptors pending in the RDR will be stored
+ *     RDR Empty: FillLevel = 0
+ *     RDR Free:  0 < FillLevel < RingSize (in descriptors)
+ *     RDR Full:  FillLevel = RingSize (in descriptors)
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_UNSUPPORTED_FEATURE_ERROR : feature is not supported
+ *     EIP202_RING_ARGUMENT_ERROR : passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_ARM_ResultDescriptor_t * ResultDscr_p,
+        const unsigned int PktRequestedCount,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrDoneCount_p,
+        unsigned int * FillLevelDscrCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * RDR Event Management API functions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Status_Get
+ *
+ * This function retrieves the RDR status information. It can be called
+ * periodically to monitor the RDR status and occurrence of fatal errors.
+ *
+ * In case of a fatal error the EIP202_RDR_Reset() function can be called to
+ * recover the RDR and bring it to the sane and safe state.
+ * The RDR SW Reset by means of the EIP202_RDR_Reset() function as well
+ * as the Global SW Reset by means of the EIP202_Global_Reset() function
+ * or the HW Reset must be performed too.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for this RDR instance.
+ *
+ * Status_p (output)
+ *     Pointer to the memory location where the RDR status information
+ *     will be stored
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Status_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RDR_Status_t * const Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_Enable
+ *
+ * This function enables the Command Descriptor Threshold and Timeout
+ * interrupts. This function does not change the current API state. It must
+ * be called every time after the RDR Threshold or Timeout interrupt occurs
+ * in order to re-enable these one-shot interrupts.
+ *
+ * The RDR Manager interrupts are routed to the EIP-201 Advanced Interrupt
+ * Controller (AIC) which in its turn can be connected to a System Interrupt
+ * Controller (SIC).
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * ThresholdDscrCount (input)
+ *     When the RDR descriptor fill level reaches the value below the number
+ *     specified by this parameter the RDR Threshold interrupt (cdr_thresh_irq)
+ *     will be generated.
+ *
+ * Timeout (input)
+ *     When the RDR descriptor fill level is non-zero and not decremented
+ *     for the amount of time specified by this parameter the RDR Timeout
+ *     interrupt (cdr_timeout_irq) will be generated.
+ *     The timeout value must be specified in 256 clock cycles
+ *     of the EIP-202 HIA clock.
+ *
+ * fIntPerPacket (input)
+ *     Descriptor-oriented or Packet-oriented Interrupts
+ *     (rd_proc_thresh_irq and rd_proc_timeout_irq)
+ *     When set to true the interrupts will be generated per packet,
+ *     otherwise interrupts are generated per descriptor
+ *
+ * This function is re-entrant for any Device.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_Enable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const unsigned int ThresholdDscrCount,
+        const unsigned int Timeout,
+        const bool fIntPerPacket);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable
+ *
+ * This function clears and disables the Result Descriptor
+ * Threshold (cdr_thresh_irq) and Timeout (cdr_timeout_irq) interrupts as well
+ * as the Descriptor (rd_proc_oflo_irq) and Buffer (rd_buf_oflo_irq) Overflow
+ * interrupts. This function does not change the current API state.
+ *
+ * This function must be called as soon as these interrupts occur.
+ * The occurrence of these interrupts can be detected
+ * by means of the EIP202_RDR_Status_Get() function, for example from an
+ * Interrupt Service Routine.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area
+ *     which contains the Device handle for the RDR instance.
+ *
+ * fOvflIntOnly (input)
+ *     When true this function will clear the buffer and descriptor overflow
+ *     interrupts only without clearing and disabling the already enabled RDR
+ *     threshold and timeout interrupts at the same time.
+ *
+ * This function is NOT re-entrant for the same Device.
+ * This function is re-entrant for different Devices.
+ *
+ * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP202_RING_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const bool fOvflIntOnly);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Dump
+ *
+ */
+void
+EIP202_RDR_Dump(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RingAdmin_t * const RingAdmin_p);
+
+
+/* end of file eip202_rdr.h */
+
+
+#endif /* EIP202_RDR_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_dscr.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_dscr.h
new file mode 100644
index 0000000..7e75c42
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_dscr.h
@@ -0,0 +1,100 @@
+/* eip202_rdr_dscr.h
+ *
+ * EIP-202 Ring Control Driver Library API Result Descriptor Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RDR_DSCR_H_
+#define EIP202_RDR_DSCR_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_WriteCB
+ * A write callback for the Ring Helper
+ */
+int
+EIP202_RDR_WriteCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int WriteIndex,
+        const unsigned int WriteCount,
+        const unsigned int TotalWriteLimit,
+        const void * Descriptors_p,
+        const int DescriptorCount,
+        const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_ReadCB
+ * A read callback for the Ring Helper
+ */
+int
+EIP202_RDR_ReadCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int ReadIndex,
+        const unsigned int ReadLimit,
+        void * Descriptors_p,
+        const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_StatusCB
+ * A status callback for the Ring Helper
+ */
+
+int
+EIP202_RDR_StatusCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        int * const DeviceReadPos_p);
+
+
+#endif /* EIP202_RDR_DSCR_H_ */
+
+
+/* end of file eip202_rdr_dscr.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_fsm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_fsm.h
new file mode 100644
index 0000000..a4e93e2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_fsm.h
@@ -0,0 +1,76 @@
+/* eip202_rdr_fsm.h
+ *
+ * EIP-202 Ring Control Driver Library API State Machine Internal Interface
+ * for Result Descriptor Ring (RDR)
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RDR_FSM_H_
+#define EIP202_RDR_FSM_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "eip202_ring_types.h"            // EIP202_Ring_Error_t
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-202 Ring Control Driver Library API States for RDR
+typedef enum
+{
+    EIP202_RDR_STATE_UNKNOWN = 1,
+    EIP202_RDR_STATE_UNINITIALIZED,
+    EIP202_RDR_STATE_INITIALIZED,
+    EIP202_RDR_STATE_FREE,
+    EIP202_RDR_STATE_FULL,
+    EIP202_RDR_STATE_FATAL_ERROR
+} EIP202_RDR_State_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_State_Set
+ *
+ * This function check whether the transition from the "CurrentState" to the
+ * "NewState" is allowed and if yes changes the former to the latter.
+ *
+  * Return value
+ *     EIP202_RING_NO_ERROR : operation is completed
+ *     EIP202_RING_ILLEGAL_IN_STATE : state transition is not allowed
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_State_Set(
+        volatile EIP202_RDR_State_t * const CurrentState,
+        const EIP202_RDR_State_t NewState);
+
+
+#endif /* EIP202_RDR_FSM_H_ */
+
+
+/* end of file eip202_rdr_fsm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_level0.h
new file mode 100644
index 0000000..af278a7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_rdr_level0.h
@@ -0,0 +1,510 @@
+/* eip202_rdr_level0.h
+ *
+ * EIP-202 Internal interface: RDR Manager
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RDR_LEVEL0_H_
+#define EIP202_RDR_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-202 HIA RDR registers
+ *****************************************************************************/
+
+#define EIP202_RDR_OFFS           4
+
+// 2 KB MMIO space for one RDR instance
+#define EIP202_RDR_BASE                   0x00000800
+#define EIP202_RDR_RING_BASE_ADDR_LO      ((EIP202_RDR_BASE) + \
+                                            (0x00 * EIP202_RDR_OFFS))
+#define EIP202_RDR_RING_BASE_ADDR_HI      ((EIP202_RDR_BASE) + \
+                                            (0x01 * EIP202_RDR_OFFS))
+#define EIP202_RDR_DATA_BASE_ADDR_LO      ((EIP202_RDR_BASE) + \
+                                            (0x02 * EIP202_RDR_OFFS))
+#define EIP202_RDR_DATA_BASE_ADDR_HI      ((EIP202_RDR_BASE) + \
+                                            (0x03 * EIP202_RDR_OFFS))
+#define EIP202_RDR_RING_SIZE              ((EIP202_RDR_BASE) + \
+                                            (0x06 * EIP202_RDR_OFFS))
+#define EIP202_RDR_DESC_SIZE              ((EIP202_RDR_BASE) + \
+                                            (0x07 * EIP202_RDR_OFFS))
+#define EIP202_RDR_CFG                    ((EIP202_RDR_BASE) + \
+                                            (0x08 * EIP202_RDR_OFFS))
+#define EIP202_RDR_DMA_CFG                ((EIP202_RDR_BASE) + \
+                                            (0x09 * EIP202_RDR_OFFS))
+#define EIP202_RDR_THRESH                 ((EIP202_RDR_BASE) + \
+                                            (0x0A * EIP202_RDR_OFFS))
+#define EIP202_RDR_PREP_COUNT             ((EIP202_RDR_BASE) + \
+                                            (0x0B * EIP202_RDR_OFFS))
+#define EIP202_RDR_PROC_COUNT             ((EIP202_RDR_BASE) + \
+                                            (0x0C * EIP202_RDR_OFFS))
+#define EIP202_RDR_PREP_PNTR              ((EIP202_RDR_BASE) + \
+                                            (0x0D * EIP202_RDR_OFFS))
+#define EIP202_RDR_PROC_PNTR              ((EIP202_RDR_BASE) + \
+                                            (0x0E * EIP202_RDR_OFFS))
+#define EIP202_RDR_STAT                   ((EIP202_RDR_BASE) + \
+                                            (0x0F * EIP202_RDR_OFFS))
+
+// Default EIP202_RDR_x register values
+#define EIP202_RDR_RING_BASE_ADDR_LO_DEFAULT       0x00000000
+#define EIP202_RDR_RING_BASE_ADDR_HI_DEFAULT       0x00000000
+#define EIP202_RDR_DATA_BASE_ADDR_LO_DEFAULT       0x00000000
+#define EIP202_RDR_DATA_BASE_ADDR_HI_DEFAULT       0x00000000
+#define EIP202_RDR_RING_SIZE_DEFAULT               0x00000000
+#define EIP202_RDR_DESC_SIZE_DEFAULT               0x00000000
+#define EIP202_RDR_CFG_DEFAULT                     0x00000000
+#define EIP202_RDR_DMA_CFG_DEFAULT                 0x01800000
+#define EIP202_RDR_THRESH_DEFAULT                  0x00000000
+#define EIP202_RDR_PREP_COUNT_DEFAULT              0x00000000
+#define EIP202_RDR_PROC_COUNT_DEFAULT              0x00000000
+#define EIP202_RDR_PREP_PNTR_DEFAULT               0x00000000
+#define EIP202_RDR_PROC_PNTR_DEFAULT               0x00000000
+// Ignore the RD FIFO size after reset for this register default value for now
+#define EIP202_RDR_STAT_DEFAULT                    0x00000000
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read32
+ *
+ * This routine writes to a Register location in the EIP-202 RDR.
+ */
+static inline uint32_t
+EIP202_RDR_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Write32
+ *
+ * This routine writes to a Register location in the EIP-202 RDR.
+ */
+static inline void
+EIP202_RDR_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline void
+EIP202_RDR_RING_BASE_ADDR_LO_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_RING_BASE_ADDR_LO,
+                       EIP202_RDR_RING_BASE_ADDR_LO_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_RING_BASE_ADDR_LO_WR(
+        Device_Handle_t Device,
+        const uint32_t LowAddr)
+{
+    EIP202_RDR_Write32(Device, EIP202_RDR_RING_BASE_ADDR_LO, LowAddr);
+}
+
+
+static inline void
+EIP202_RDR_RING_BASE_ADDR_HI_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_RING_BASE_ADDR_HI,
+                       EIP202_RDR_RING_BASE_ADDR_HI_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_RING_BASE_ADDR_HI_WR(
+        Device_Handle_t Device,
+        const uint32_t HiAddr)
+{
+    EIP202_RDR_Write32(Device, EIP202_RDR_RING_BASE_ADDR_HI, HiAddr);
+}
+
+
+static inline void
+EIP202_RDR_RING_SIZE_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_RING_SIZE,
+                       EIP202_RDR_RING_SIZE_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_RING_SIZE_WR(
+        Device_Handle_t Device,
+        const uint32_t RDRWordCount)
+{
+    uint32_t RegVal = EIP202_RDR_RING_SIZE_DEFAULT;
+
+    RegVal |= ((((uint32_t)RDRWordCount) & MASK_22_BITS) << 2);
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_RING_SIZE, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_DESC_SIZE_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_DESC_SIZE,
+                       EIP202_RDR_DESC_SIZE_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_DESC_SIZE_WR(
+        Device_Handle_t Device,
+        const uint8_t DscrWordCount,
+        const uint8_t DscrOffsWordCount,
+        const bool f64bit)
+{
+    uint32_t RegVal = EIP202_RDR_DESC_SIZE_DEFAULT;
+
+    if(f64bit)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)DscrOffsWordCount) & MASK_8_BITS) << 16);
+    RegVal |= ((((uint32_t)DscrWordCount)     & MASK_8_BITS)      );
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_DESC_SIZE, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_CFG_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_CFG,
+                       EIP202_RDR_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_CFG_WR(
+        Device_Handle_t Device,
+        const uint16_t RDFetchWordCount,
+        const uint16_t RDFetchThreshWordCount,
+        const bool fOwnEnable)
+{
+    uint32_t RegVal = EIP202_RDR_CFG_DEFAULT;
+
+    if(fOwnEnable)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)RDFetchThreshWordCount) & MASK_12_BITS)  << 16);
+    RegVal |= ((((uint32_t)RDFetchWordCount)       & MASK_16_BITS)      );
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_CFG, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_DMA_CFG_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_DMA_CFG,
+                       EIP202_RDR_DMA_CFG_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_DMA_CFG_WR(
+        Device_Handle_t Device,
+        const uint8_t RDSwap,
+        const uint8_t DataSwap,
+        const bool fResBuf,
+        const bool fCtrlBuf,
+        const bool fOwnBuf,
+        const uint8_t WrCache,
+        const uint8_t RdCache,
+        const uint8_t RdProtection,
+        const uint8_t DataProtection,
+        const bool fPadToOffset)
+{
+    uint32_t RegVal = EIP202_RDR_DMA_CFG_DEFAULT;
+
+    if(fPadToOffset)
+        RegVal |= BIT_28;
+
+    RegVal &= (~BIT_24);
+    if(fOwnBuf)
+        RegVal |= BIT_24;
+
+    RegVal &= (~BIT_23);
+    if(fCtrlBuf)
+        RegVal |= BIT_23;
+
+    if(fResBuf)
+        RegVal |= BIT_22;
+
+    RegVal |= ((((uint32_t)RdCache)        & MASK_3_BITS) << 29);
+    RegVal |= ((((uint32_t)WrCache)        & MASK_3_BITS) << 25);
+    RegVal |= ((((uint32_t)DataProtection) & MASK_4_BITS) << 12);
+    RegVal |= ((((uint32_t)DataSwap)       & MASK_4_BITS) << 8);
+    RegVal |= ((((uint32_t)RdProtection)   & MASK_4_BITS) << 4);
+    RegVal |= ((((uint32_t)RDSwap)         & MASK_4_BITS));
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_DMA_CFG, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_THRESH_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_THRESH,
+                       EIP202_RDR_THRESH_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_THRESH_WR(
+        Device_Handle_t Device,
+        const uint32_t RDThreshWordCount,
+        const bool fProcPktMode,
+        const uint8_t RDTimeout)
+{
+    uint32_t RegVal = EIP202_RDR_THRESH_DEFAULT;
+
+    if(fProcPktMode)
+        RegVal |= BIT_23;
+
+    RegVal |= (RDThreshWordCount      & MASK_22_BITS);
+    RegVal |= ((((uint32_t)RDTimeout) & MASK_8_BITS) << 24);
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_THRESH, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_PREP_COUNT_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_PREP_COUNT,
+                       EIP202_RDR_PREP_COUNT_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_PREP_COUNT_WR(
+        Device_Handle_t Device,
+        const uint16_t RDCount,
+        const bool fClearCount)
+{
+    uint32_t RegVal = EIP202_RDR_PREP_COUNT_DEFAULT;
+
+    if(fClearCount)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)RDCount) & MASK_14_BITS) << 2);
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_PREP_COUNT, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_PREP_COUNT_RD(
+        Device_Handle_t Device,
+        uint32_t * const PrepRDWordCount_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_RDR_Read32(Device, EIP202_RDR_PREP_COUNT);
+
+    *PrepRDWordCount_p   = (uint32_t)((RegVal >> 2) & MASK_22_BITS);
+}
+
+
+static inline void
+EIP202_RDR_PROC_COUNT_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_PROC_COUNT,
+                       EIP202_RDR_PROC_COUNT_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_PROC_COUNT_WR(
+        Device_Handle_t Device,
+        const uint16_t RDWordCount,
+        const uint8_t PktCount,
+        const bool fClearCount)
+{
+    uint32_t RegVal = EIP202_RDR_PROC_COUNT_DEFAULT;
+
+    if(fClearCount)
+        RegVal |= BIT_31;
+
+    RegVal |= ((((uint32_t)RDWordCount)  & MASK_14_BITS) << 2);
+    RegVal |= ((((uint32_t)PktCount)     & MASK_7_BITS)  << 24);
+
+    EIP202_RDR_Write32(Device, EIP202_RDR_PROC_COUNT, RegVal);
+}
+
+
+static inline void
+EIP202_RDR_PROC_COUNT_RD(
+        Device_Handle_t Device,
+        uint32_t * const ProcRDWordCount_p,
+        uint8_t * const ProcPktWordCount_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_RDR_Read32(Device, EIP202_RDR_PROC_COUNT);
+
+    *ProcRDWordCount_p    = (uint32_t)((RegVal >> 2)  & MASK_22_BITS);
+    *ProcPktWordCount_p   =  (uint8_t)((RegVal >> 24) & MASK_7_BITS);
+}
+
+
+static inline void
+EIP202_RDR_PREP_PNTR_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_PREP_PNTR,
+                       EIP202_RDR_PREP_PNTR_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_PROC_PNTR_DEFAULT_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_PROC_PNTR,
+                       EIP202_RDR_PROC_PNTR_DEFAULT);
+}
+
+
+static inline void
+EIP202_RDR_STAT_RD(
+        Device_Handle_t Device,
+        bool * const fDMAErrorIrq,
+        bool * const fTreshIrq,
+        bool * const fErrorIrq,
+        bool * const fOuflowIrq,
+        bool * const fTimeoutIrq,
+        bool * const fBufOfloIrq,
+        bool * const fProcOfloIrq,
+        uint16_t * const RDFIFOWordCount)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_RDR_Read32(Device, EIP202_RDR_STAT);
+
+    *fDMAErrorIrq      = ((RegVal & BIT_0) != 0);
+    *fErrorIrq         = ((RegVal & BIT_2) != 0);
+    *fOuflowIrq        = ((RegVal & BIT_3) != 0);
+    *fTreshIrq         = ((RegVal & BIT_4) != 0);
+    *fTimeoutIrq       = ((RegVal & BIT_5) != 0);
+    *fBufOfloIrq       = ((RegVal & BIT_6) != 0);
+    *fProcOfloIrq      = ((RegVal & BIT_7) != 0);
+    *RDFIFOWordCount   = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_RDR_STAT_FIFO_SIZE_RD(
+        Device_Handle_t Device,
+        uint16_t * const RDFIFOWordCount)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP202_RDR_Read32(Device, EIP202_RDR_STAT);
+
+    *RDFIFOWordCount   = (uint16_t)((RegVal >> 16) & MASK_12_BITS);
+}
+
+
+static inline void
+EIP202_RDR_STAT_CLEAR_ALL_IRQ_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_STAT,
+                       (uint32_t)(EIP202_RDR_STAT_DEFAULT | MASK_8_BITS));
+}
+
+
+static inline void
+EIP202_RDR_STAT_CLEAR_DSCR_BUF_OFLO_IRQ_WR(
+        Device_Handle_t Device)
+{
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_STAT,
+                       (uint32_t)(EIP202_RDR_STAT_DEFAULT | BIT_7 | BIT_6));
+}
+
+
+#endif /* EIP202_RDR_LEVEL0_H_ */
+
+
+/* end of file eip202_rdr_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_internal.h
new file mode 100644
index 0000000..5f61734
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_internal.h
@@ -0,0 +1,131 @@
+/* eip202_ring_internal.h
+ *
+ * EIP-202 Ring Control Driver Library Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP202_RING_INTERNAL_H_
+#define EIP202_RING_INTERNAL_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"       // EIP202_RING_STRICT_ARGS
+
+// EIP-202 Ring Driver Library Types API
+#include "eip202_ring_types.h"   // EIP202_* types
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"       // types of the DMA resource API
+
+// Ring Helper API
+#include "ringhelper.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// RDR ownership word pattern
+#define EIP202_RDR_OWNERSHIP_WORD_PATTERN       0xAAAAAAAAU
+
+// CDR I/O Area, used internally
+typedef struct
+{
+    Device_Handle_t Device;
+    unsigned int State;
+    RingHelper_t RingHelper;
+    RingHelper_CallbackInterface_t RingHelperCallbacks;
+    DMAResource_Handle_t RingHandle;
+    uint32_t DescOffsWordCount;
+    uint32_t RingSizeWordCount;
+    uint32_t CountRD;
+    bool fValidCountRD;
+    bool fATP;
+} EIP202_CDR_True_IOArea_t;
+
+// RDR I/O Area, used internally
+typedef struct
+{
+    Device_Handle_t Device;
+    unsigned int State;
+    RingHelper_t RingHelper;
+    RingHelper_CallbackInterface_t RingHelperCallbacks;
+    DMAResource_Handle_t RingHandle;
+    uint32_t DescOffsWordCount;
+    uint32_t RingSizeWordCount;
+    uint32_t TokenOffsetWordCount;
+    unsigned int AcknowledgedRDCount;
+    unsigned int AcknowledgedPktCount;
+    unsigned int RDToGetCount;
+    unsigned int PktToGetCount;
+    bool PacketFound;
+} EIP202_RDR_True_IOArea_t;
+
+#define CDRIOAREA(_p) ((volatile EIP202_CDR_True_IOArea_t *)_p)
+#define RDRIOAREA(_p) ((volatile EIP202_RDR_True_IOArea_t *)_p)
+
+#ifdef EIP202_RING_STRICT_ARGS
+#define EIP202_RING_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return EIP202_RING_ARGUMENT_ERROR;
+#define EIP202_RING_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return EIP202_RING_ARGUMENT_ERROR;
+#define EIP202_RING_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return EIP202_RING_ARGUMENT_ERROR;
+#define EIP202_RING_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return EIP202_RING_ARGUMENT_ERROR;
+#else
+/* EIP202_RING_STRICT_ARGS undefined */
+#define EIP202_RING_CHECK_POINTER(_p)
+#define EIP202_RING_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP202_RING_CHECK_INT_ATLEAST(_i, _min)
+#define EIP202_RING_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP202_RING_STRICT_ARGS */
+
+#define TEST_SIZEOF(type, size) \
+    extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP202_CDR_True_IOArea_t, EIP202_IOAREA_REQUIRED_SIZE);
+TEST_SIZEOF(EIP202_RDR_True_IOArea_t, EIP202_IOAREA_REQUIRED_SIZE);
+
+
+#endif /* EIP202_RING_INTERNAL_H_ */
+
+
+/* end of file eip202_ring_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_types.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_types.h
new file mode 100644
index 0000000..ea6fc59
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip202_ring_types.h
@@ -0,0 +1,354 @@
+/* eip202_ring_types.h
+ *
+ * EIP-202 Ring Control Driver Library Public Interface:
+ * Common Type Definitions for CDR and RDR
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef INCLUDE_GUARD_EIP202_RING_TYPES_H
+#define INCLUDE_GUARD_EIP202_RING_TYPES_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // types of the DMA resource API
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// I/O Area size for one CDR or RDR instance
+#define EIP202_IOAREA_REQUIRED_SIZE           300
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Ring_Error_t
+ *
+ * Status (error) code type returned by these API functions
+ * See each function "Return value" for details.
+ *
+ * EIP202_RING_NO_ERROR : successful completion of the call.
+ * EIP202_RING_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ * EIP202_RING_ARGUMENT_ERROR :  invalid argument for a function parameter.
+ * EIP202_RING_BUSY_RETRY_LATER : Device is busy.
+ * EIP202_RING_ILLEGAL_IN_STATE : illegal state transition
+ */
+typedef enum
+{
+    EIP202_RING_NO_ERROR = 0,
+    EIP202_RING_UNSUPPORTED_FEATURE_ERROR,
+    EIP202_RING_ARGUMENT_ERROR,
+    EIP202_RING_ILLEGAL_IN_STATE
+} EIP202_Ring_Error_t;
+
+// place holder for device specific internal data
+typedef struct
+{
+    uint32_t placeholder[EIP202_IOAREA_REQUIRED_SIZE];
+} EIP202_Ring_IOArea_t;
+
+typedef enum
+{
+    // Endianness Conversion (EC) in the EIP-202 HW master interface setting
+    // for different types of DMA data.
+    // Default setting is 0 which means that the EC in the EIP-202 hardware
+    // is disabled.
+    EIP202_RING_BYTESWAP_TOKEN           = BIT_0, // Enables Token Data EC
+    EIP202_RING_BYTESWAP_DESCRIPTOR      = BIT_1, // Enables Descriptor Data EC
+    EIP202_RING_BYTESWAP_PACKET          = BIT_2  // Enables Packet Data EC
+} EIP202_Ring_DMA_ByteSwap_DataType_t;
+
+// Bit-mask for the events defined by EIP202_Ring_DMA_ByteSwap_DataType_t
+typedef uint32_t EIP202_Ring_DMA_ByteSwap_DataType_Mask_t;
+
+// Endianness Conversion method
+// One (or several) of the following methods must be configured in case
+// the endianness conversion is enabled for one (or several) of
+// the DMA data types:
+typedef enum
+{
+    // Swap bytes within each 32 bit word
+    EIP202_RING_BYTE_SWAP_METHOD_32    = BIT_0,
+
+    // Swap 32 bit chunks within each 64 bit chunk
+    EIP202_RING_BYTE_SWAP_METHOD_64    = BIT_1,
+
+    // Swap 64 bit chunks within each 128 bit chunk
+    EIP202_RING_BYTE_SWAP_METHOD_128   = BIT_2,
+
+    // Swap 128 bit chunks within each 256 bit chunk
+    EIP202_RING_BYTE_SWAP_METHOD_256   = BIT_3
+} EIP202_Ring_DMA_ByteSwap_Method_t;
+
+// Bit-mask for the events defined by EIP202_Ring_DMA_ByteSwap_DataType_t
+typedef uint32_t EIP202_Ring_DMA_ByteSwap_Method_Mask_t;
+
+// Physical (bus) address that can be used for DMA by the device
+typedef struct
+{
+    // 32-bit physical bus address
+    uint32_t Addr;
+
+    // upper 32-bit part of a 64-bit physical address
+    // Note: this value has to be provided only for 64-bit addresses,
+    // in this case Addr field provides the lower 32-bit part
+    // of the 64-bit address, for 32bit addresses this field is ignored,
+    // and should be set to 0.
+    uint32_t UpperAddr;
+
+} EIP202_DeviceAddress_t;
+
+// 64-bit DMA address support
+typedef enum
+{
+    EIP202_RING_64BIT_DMA_DISABLED,  // 32-bit DMA addresses in descriptors only
+    EIP202_RING_64BIT_DMA_DSCR_PTR,  // 64-bit DMA addresses in descriptors
+    EIP202_RING_64BIT_DMA_EXT_ADDR   // Enables extended DMA addresses, e.g.
+                                    // 32-bit DMA addresses in descriptors
+                                    // are added to a 64-bit base address
+                                    // (only one 64-bit base address can be
+                                    // defined for tokens and one for
+                                    // packet data )
+} EIP202_Ring_DMA_Address_Mode_t;
+
+// The EIP-202 HW master interface hardware data width
+typedef enum
+{
+    EIP202_RING_DMA_ALIGNMENT_4_BYTES   = 0, // 4 bytes
+    EIP202_RING_DMA_ALIGNMENT_8_BYTES   = 1, // 8 bytes
+    EIP202_RING_DMA_ALIGNMENT_16_BYTES  = 2, // 16 bytes
+    EIP202_RING_DMA_ALIGNMENT_32_BYTES  = 3  // 32 bytes
+} EIP202_Ring_DMA_Alignment_t;
+
+// Bufferability control
+typedef enum
+{
+    // Enables bufferability control for ownership word DMA writes
+    EIP202_RING_BUF_CTRL_OWN_DMA_WRITES              = BIT_0,
+
+    // Enables bufferability control for write/Read cache type control
+    EIP202_RING_BUF_CTRL_WR_RD_CACHE                 = BIT_1,
+
+    // Enables bufferability control for Result Token DMA writes
+    // Note: this can be enabled for RDR only
+    EIP202_RING_BUF_CTRL_RESULT_TOKEN_DMA_WRITES     = BIT_2,
+
+    // Enables bufferability control for Descriptor Control Word DMA writes
+    // Note: this can be enabled for RDR only
+    EIP202_RING_BUF_CTRL_RDR_CONTROL_DMA_WRITES      = BIT_3
+
+} EIP202_Ring_Bufferability_Control_t;
+
+// Bit-mask for the events defined by EIP202_Ring_Bufferability_Control_t
+typedef uint32_t    EIP202_Ring_Bufferability_Settings_t;
+
+// Autonomous Ring Mode (ARM) descriptor ring settings
+typedef struct
+{
+    // Master Data Bus Width (in 32-bit words)
+    uint32_t                                DataBusWidthWordCount;
+
+    // Endianness Conversion (EC) settings
+    // Mask enables the EC per DMA data type:
+    // 1) Token, 2) Descriptor and 3) Packet data.
+    EIP202_Ring_DMA_ByteSwap_DataType_Mask_t ByteSwap_DataType_Mask;
+
+    // Endianness Conversion method per DMA data type
+    EIP202_Ring_DMA_ByteSwap_Method_Mask_t   ByteSwap_Token_Mask;
+    EIP202_Ring_DMA_ByteSwap_Method_Mask_t   ByteSwap_Descriptor_Mask;
+    EIP202_Ring_DMA_ByteSwap_Method_Mask_t   ByteSwap_Packet_Mask;
+
+    // Bufferability control
+    EIP202_Ring_Bufferability_Settings_t     Bufferability;
+
+    // Enable 64-bit DMA address support
+    // Two different 64-bit DMA modes exist:
+    //      1) 64-bit descriptor pointer and
+    //      2) extended addressing.
+    EIP202_Ring_DMA_Address_Mode_t           DMA_AddressMode;
+
+    // Ring Size, in 32-bit words:
+    //      The minimum value is the “Command Descriptor Offset”, see below.
+    //      The maximum value is 4194303
+    //      (setting a ring size of one word below 16M Byte).
+    uint32_t                                RingSizeWordCount;
+
+    // Ring DMA resource handle
+    DMAResource_Handle_t                    RingDMA_Handle;
+
+    // Ring physical address that can be used for DMA
+    EIP202_DeviceAddress_t                   RingDMA_Address;
+
+    // Command/Result Descriptor Size (in 32-bit words)
+    // 1) For CDR:
+    // The minimum value in 32-bit address mode is 3 without the Additional
+    // Token Pointer (ATP) and 4 with ATP.
+    // The minimum value in 64-bit address mode is 5 without ATP and 7 with ATP.
+    // The maximum value is the “Command Descriptor FIFO Size”,
+    // independent of the addressing mode.
+    // 2) For RDR:
+    // The minimum value is 3 for 32-bit addressable systems and
+    // 5 for 64-bit addressable systems.
+    // The maximum value is the “Result Descriptor FIFO Size”,
+    // independent of the addressing mode.
+    uint32_t                                DscrSizeWordCount;
+
+    // Descriptor Offset (in 32-bit words)
+    // Can be used to align descriptor size for cache-line size, for example)
+    uint32_t                                DscrOffsWordCount;
+
+    // Offset of result token with respect to start of descriptor.
+    uint32_t                                TokenOffsetWordCount;
+
+    // Command/Result Descriptor Fetch Size (in 32-bit words)
+    // The number of 32-bit words of Descriptor data that
+    // the Ring Manager attempts to fetch from the ring in Host memory in one
+    // contiguous block to the internal FIFO. The Ring Manager waits until
+    // the “Descriptor Fetch Threshold” (see below) is exceeded.
+    // Then it fetches “Descriptor Fetch Size” 32-bit words or as many
+    // words of descriptor data as available, from the ring.
+    // This value must be an integer multiple of the “Descriptor Offset”
+    // and should not exceed the “Descriptor FIFO Size”.
+    uint32_t                                DscrFetchSizeWordCount;
+
+    // Command/Result Descriptor Fetch Threshold (in 32-bit words)
+    // In Autonomous Ring Mode this is the number of 32-bit words that must be
+    // free in the Descriptor FIFO before it fetches a new block of
+    // Descriptors. This value must be an integer multiple of
+    // the “Descriptor Size” rounded up to a whole multiple of
+    // the “Master Data Bus Width”, and should not exceed the
+    // “Descriptor FIFO Size”.
+    // Example: if the “Command Descriptor FIFO Size” is 5 words and the master
+    //          data bus width is 128 bits (4 words), then this register must
+    //          be programmed to at least value 8, since that is the next
+    //          integer multiple of 4 after 5.
+    uint32_t                                DscrThresholdWordCount;
+
+    // Command/Result Descriptor Interrupt Threshold
+    // 1) For CDR  (in Descriptors):
+    // The value in this field is compared with the number of prepared Command
+    // Descriptors pending in the CDR. When that number is less than or equal
+    // to the value set in this field the cd_thresh_irq interrupt fires.
+    // 2) For RDR  (in Descriptors or in Packets):
+    // The rd_proc_thresh_irq interrupt is fired when the number of
+    // the Processed Result Descriptors/Packets for the RDR exceeds the value
+    // set by this parameter. The maximum number of packets is 127.
+    uint32_t                                IntThresholdDscrCount;
+
+    // Command/Result Descriptor Interrupt Timeout
+    // (units of 256 clock cycles of the HIA clock)
+    // 1) For CDR:
+    // The cd_timeout_irq interrupt is fired when the number of prepared
+    // command descriptors pending in the CDR is non-zero and not decremented
+    // for the amount of time specified by this value.
+    // 2) For RDR:
+    // The rd_proc_timeout_irq interrupt is fired when the number of Processed
+    // Result Descriptors pending in the RDR is non-zero, remains constant and
+    // has not reached the value specified by the “Result Descriptor Interrupt
+    // Threshold” parameter for the amount of time specified by this value.
+    // 3) For CDR and RDR:
+    // A value of zero disables the interrupt and stops the timeout counter
+    // (useful to reduce power consumption).
+    uint32_t                                IntTimeoutDscrCount;
+
+} EIP202_ARM_Ring_Settings_t;
+
+// EIP-202 HW options
+typedef struct
+{
+    // Number of statically configured Descriptor Rings
+    uint8_t NofRings;
+
+    // Number of statically configured Processing Engines,
+    // value 0 indicates 8 PEs
+    uint8_t NofPes;
+
+    // If true then 64 bit descriptors will contain a particle
+    // size/fill level extension word to allow particle sizes larger
+    // than 1 MB.
+    bool fExpPlf;
+
+    // Command Descriptor FIFO size, the actual size is 2^CF_Size 32-bit
+    // words.
+    uint8_t CF_Size;
+
+    // Result Descriptor FIFO size, the actual size is 2^RF_Size 32-bit
+    // words.
+    uint8_t RF_Size;
+
+    // Host interface type:
+    // 0 = PLB, 1 = AHB, 2 = TCM, 3 = AXI
+    uint8_t HostIfc;
+
+    // Maximum supported DMA length is 2^(DMA_Len+1) – 1 bytes
+    uint8_t DMA_Len;
+
+    // Host interface data width:
+    // 0 = 32 bits, 1 = 64 bits, 2 = 128 bits, 3 = 256 bits
+    uint8_t HDW;
+
+    // Target access block alignment. If this value is larger than 0,
+    // the distance between 2 rings, 2 AICs and between the DFE and the DSE
+    // in the slave memory map is increased by a factor of 2^TgtAlign.
+    // This means that ring control registers start at 2^(TgtAlign+11) Byte
+    // boundaries (or a 2^(TgtAlign+12) Byte boundary for a combined
+    // CDR/RDR block), the DFE and DSE will start at a 2^(TgtAlign+10) Byte
+    // boundary and AICs will start at 2^(TgtAlign+8) Byte boundaries.
+    uint8_t TgtAlign;
+
+    // 64-bit addressing mode:
+    // false = 32-bit addressing,
+    // true = 64-bit addressing
+    bool fAddr64;
+} EIP202_Ring_Options_t;
+
+// Ring Admin data
+typedef struct
+{
+    unsigned int RingSizeWordCount;
+    unsigned int DescOffsWordCount;
+
+    unsigned int IN_Size;
+    unsigned int IN_Tail;
+
+    unsigned int OUT_Size;
+    unsigned int OUT_Head;
+
+    bool fSeparate;
+} EIP202_RingAdmin_t;
+
+
+#endif /* INCLUDE_GUARD_EIP202_RING_TYPES_H */
+
+
+/* end of file eip202_ring_types.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_hw_interface.h
new file mode 100644
index 0000000..9880cd5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_hw_interface.h
@@ -0,0 +1,115 @@
+/* eip206_hw_interface.h
+ *
+ * EIP-206 Processing Engine HW interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP206_HW_INTERFACE_H_
+#define EIP206_HW_INTERFACE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip206.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint16_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-206 Processing Engine registers
+ *****************************************************************************/
+// Processing Engine EIP number (0xCE) and complement (0x31)
+#define EIP206_SIGNATURE              ((uint16_t)0x31CE)
+
+#define EIP206_REG_OFFS               4
+#define EIP206_REG_MAP_SIZE           8192
+
+// Processing Packet Engine n (n - number of the PE)
+// Input Side
+#define EIP206_IN_REG_DBUF_TRESH(n)   ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_IN_DBUF_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+
+#define EIP206_IN_REG_TBUF_TRESH(n)   ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_IN_TBUF_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+
+// Output Side
+#define EIP206_OUT_REG_DBUF_TRESH(n)  ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_OUT_DBUF_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+
+#define EIP206_OUT_REG_TBUF_TRESH(n)  ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_OUT_TBUF_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+
+// PE Options and Version
+#define EIP206_REG_DEBUG(n)           ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_VER_BASE) - \
+                                        (0x01 * EIP206_REG_OFFS)))
+#define EIP206_REG_OPTIONS(n)         ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_VER_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+#define EIP206_REG_VERSION(n)         ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_VER_BASE) + \
+                                        (0x01 * EIP206_REG_OFFS)))
+
+// Default EIP206_IN_REG_DBUF_TRESH register value
+#define EIP206_IN_REG_DBUF_TRESH_DEFAULT        0x00000000
+
+// Default EIP206_IN_REG_TBUF_TRESH register value
+#define EIP206_IN_REG_TBUF_TRESH_DEFAULT        0x00000000
+
+// Default EIP206_OUT_REG_DBUF_TRESH register value
+#define EIP206_OUT_REG_DBUF_TRESH_DEFAULT       0x00000000
+
+// Default EIP206_OUT_REG_TBUF_TRESH register value
+#define EIP206_OUT_REG_TBUF_TRESH_DEFAULT       0x00000000
+
+
+// ARC4 Size Small/Large
+#define EIP206_ARC4_REG_SIZE(n)       ((EIP206_REG_MAP_SIZE * n) + \
+                                       ((EIP206_ARC4_BASE) + \
+                                        (0x00 * EIP206_REG_OFFS)))
+
+
+// Default EIP206_ARC4_REG_SIZE_DEFAULT register value
+#define EIP206_ARC4_REG_SIZE_DEFAULT            0x00000000
+
+#endif /* EIP206_HW_INTERFACE_H_ */
+
+
+/* end of file eip206_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_level0.h
new file mode 100644
index 0000000..dc49a45
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip206_level0.h
@@ -0,0 +1,298 @@
+/* eip206_level0.h
+ *
+ * EIP-206 Processing Engine Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP206_LEVEL0_H_
+#define EIP206_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// EIP-206 HW interface
+#include "eip206_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP206_Read32
+ *
+ * This routine writes to a Register location in the EIP-206.
+ */
+static inline uint32_t
+EIP206_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP206_Write32
+ *
+ * This routine writes to a Register location in the EIP-206.
+ */
+static inline void
+EIP206_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline bool
+EIP206_REV_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP206_SIGNATURE);
+}
+
+
+static inline void
+EIP206_EIP_REV_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP206_Read32(Device, EIP206_REG_VERSION(PEnr));
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP206_OPTIONS_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint8_t * const PE_Type,
+        uint8_t * const InClassifier,
+        uint8_t * const OutClassifier,
+        uint8_t * const NofMAC_Channels,
+        uint8_t * const InDbufSizeKB,
+        uint8_t * const InTbufSizeKB,
+        uint8_t * const OutDbufSizeKB,
+        uint8_t * const OutTbufSizeKB)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP206_Read32(Device, EIP206_REG_OPTIONS(PEnr));
+
+    *OutTbufSizeKB   = (uint8_t)((RevRegVal >> 28) & MASK_4_BITS);
+    *OutDbufSizeKB   = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *InTbufSizeKB    = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *InDbufSizeKB    = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *NofMAC_Channels = (uint8_t)((RevRegVal >> 12) & MASK_4_BITS);
+    *OutClassifier   = (uint8_t)((RevRegVal >> 10) & MASK_2_BITS);
+    *InClassifier    = (uint8_t)((RevRegVal >> 8)  & MASK_2_BITS);
+    *PE_Type         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP206_IN_DEBUG_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const bool fBypass,
+        const bool fInFlightClear,
+        const bool fMetaEnb)
+{
+    uint32_t RegVal = 0;
+
+    if (fBypass)
+        RegVal |= BIT_0;
+
+    if (fInFlightClear)
+        RegVal |= BIT_16;
+
+    if (fMetaEnb)
+        RegVal |= BIT_31;
+    EIP206_Write32(Device,EIP206_REG_DEBUG(PEnr),RegVal);
+}
+
+
+static inline void
+EIP206_IN_DBUF_THRESH_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP206_Write32(Device,
+                   EIP206_IN_REG_DBUF_TRESH(PEnr),
+                   EIP206_IN_REG_DBUF_TRESH_DEFAULT);
+}
+
+
+static inline void
+EIP206_IN_DBUF_THRESH_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t PktTresh,
+        const uint8_t MinTresh,
+        const uint8_t MaxTresh)
+{
+    uint32_t RegVal = EIP206_IN_REG_DBUF_TRESH_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)PktTresh) & MASK_8_BITS));
+    RegVal |= (uint32_t)((((uint32_t)MaxTresh) & MASK_4_BITS) << 12);
+    RegVal |= (uint32_t)((((uint32_t)MinTresh) & MASK_4_BITS) << 8);
+
+    EIP206_Write32(Device, EIP206_IN_REG_DBUF_TRESH(PEnr), RegVal);
+}
+
+
+static inline void
+EIP206_IN_TBUF_THRESH_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP206_Write32(Device,
+                   EIP206_IN_REG_TBUF_TRESH(PEnr),
+                   EIP206_IN_REG_TBUF_TRESH_DEFAULT);
+}
+
+
+static inline void
+EIP206_IN_TBUF_THRESH_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t PktTresh,
+        const uint8_t MinTresh,
+        const uint8_t MaxTresh)
+{
+    uint32_t RegVal = EIP206_IN_REG_TBUF_TRESH_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)PktTresh) & MASK_8_BITS));
+    RegVal |= (uint32_t)((((uint32_t)MaxTresh) & MASK_4_BITS) << 12);
+    RegVal |= (uint32_t)((((uint32_t)MinTresh) & MASK_4_BITS) << 8);
+
+    EIP206_Write32(Device, EIP206_IN_REG_TBUF_TRESH(PEnr), RegVal);
+}
+
+
+static inline void
+EIP206_OUT_DBUF_THRESH_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP206_Write32(Device,
+                   EIP206_OUT_REG_DBUF_TRESH(PEnr),
+                   EIP206_OUT_REG_DBUF_TRESH_DEFAULT);
+}
+
+
+static inline void
+EIP206_OUT_DBUF_THRESH_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t MinTresh,
+        const uint8_t MaxTresh)
+{
+    uint32_t RegVal = EIP206_OUT_REG_DBUF_TRESH_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)MaxTresh) & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)MinTresh) & MASK_4_BITS));
+
+    EIP206_Write32(Device, EIP206_OUT_REG_DBUF_TRESH(PEnr), RegVal);
+}
+
+
+static inline void
+EIP206_OUT_TBUF_THRESH_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP206_Write32(Device,
+                   EIP206_OUT_REG_TBUF_TRESH(PEnr),
+                   EIP206_OUT_REG_TBUF_TRESH_DEFAULT);
+}
+
+
+static inline void
+EIP206_OUT_TBUF_THRESH_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t MinTresh,
+        const uint8_t MaxTresh)
+{
+    uint32_t RegVal = EIP206_OUT_REG_TBUF_TRESH_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)MaxTresh) & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)MinTresh) & MASK_4_BITS));
+
+    EIP206_Write32(Device, EIP206_OUT_REG_TBUF_TRESH(PEnr), RegVal);
+}
+
+static inline void
+EIP206_ARC4_SIZE_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const bool fLarge)
+{
+    uint32_t RegVal = EIP206_ARC4_REG_SIZE_DEFAULT;
+
+    if(fLarge)
+        RegVal |= BIT_0;
+
+    EIP206_Write32(Device, EIP206_ARC4_REG_SIZE(PEnr), RegVal);
+}
+
+
+
+#endif /* EIP206_LEVEL0_H_ */
+
+
+/* end of file eip206_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_dtl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_dtl.h
new file mode 100644
index 0000000..40ddc3a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_dtl.h
@@ -0,0 +1,222 @@
+/* eip207_flow_dtl.h
+ *
+ * EIP-207 Flow Control API, FLUE DTL extensions:
+ *      Large Transform record support,
+ *      Transform records addition,
+ *      Flow and Transform records removal,
+ *      Direct Transform Record Lookup
+ *
+ * This API should be used for the In-line IPsec and Fast-Path IPsec
+ * use cases only!
+ *
+ * This API is not re-entrant.
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_DTL_H_
+#define EIP207_FLOW_DTL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"           // uint8_t, uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"         // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // DMAResource_Handle_t
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"  // EIP207_FLOW_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_FR_Remove
+ *
+ * This function removes the flow record from
+ * the HT and the classification engine so that the engine can not look it up.
+ *
+ * Note: only one flow record can be removed at a time for one instance
+ *       of the classification engine.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be removed from
+ *
+ * FR_Dscr_p (input)
+ *     Pointer to the flow descriptor data structure that describes
+ *     the flow record to be removed. The flow descriptor buffer can
+ *     be discarded after the flow record is removed.
+ *     The flow descriptor pointer cannot be 0.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_RECORD_REMOVE_BUSY
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_FR_Remove(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_WordCount_Get
+ *
+ * This function returns the required size of one Large Transform Record
+ * (in 32-bit words).
+ */
+unsigned int
+EIP207_Flow_DTL_TR_Large_WordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Add
+ *
+ * This function adds the provided transform record to the Hash Table
+ * so that the classification device can look it up (Direct Transform Lookup).
+ *
+ * This function returns the EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Flow Control Driver Library configuration
+ * and the used EIP-207 HW capabilities.
+ *
+ * Note: this function must be called only for those transform records
+ *       which can be directly looked up by the Classification device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be added.
+ *
+ * TR_Dscr_p (input)
+ *     Pointer to the data structure that describes the transform record.
+ *     This descriptor must exist along with the record it describes until
+ *     that record is removed by the EIP207_Flow_DTL_TR_Remove() function.
+ *     The transform descriptor pointer cannot be 0.
+ *
+ * XformInData_p (input)
+ *     Pointer to the data structure that contains the input data that will
+ *     be used for adding the transform record. The buffer holding this data
+ *     structure can be freed after this function returns.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Add(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        const EIP207_Flow_TR_InputData_t * const XformInData_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_Read
+ *
+ * This function reads output data from the provided large transform record.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be removed from.
+ *
+ * TR_Dscr_p (input)
+ *     Pointer to the transform record descriptor. The transform record
+ *     descriptor is only used during this function execution.
+ *     It can be discarded after this function returns.
+ *
+ * XformData_p (output)
+ *     Pointer to the data structure where the read transform data will
+ *     be stored.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Large_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        EIP207_Flow_TR_OutputData_t * const XformData_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Remove
+ *
+ * This function removes the requested transform record from the classification
+ * engine.
+ *
+ * Note: this function must be called only for those transform records
+ *       which can be directly looked up by the Classification device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be removed from.
+ *
+ * TR_Dscr_p (input)
+ *     Pointer to the transform record descriptor.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Remove(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p);
+
+
+#endif /* EIP207_FLOW_DTL_H_ */
+
+
+/* end of file eip207_flow_dtl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_generic.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_generic.h
new file mode 100644
index 0000000..c0985ff
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_generic.h
@@ -0,0 +1,641 @@
+/* eip207_flow_generic.h
+ *
+ * EIP-207 Flow Control Generic API:
+ *      Flow hash table initialization,
+ *      Flow and Transform records creation and removal
+ *
+ * This API is not re-entrant.
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_GENERIC_H_
+#define EIP207_FLOW_GENERIC_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLOW_SELECT_IPV4                BIT_0
+#define EIP207_FLOW_SELECT_IPV6                BIT_1
+
+// Hash ID size in 32-bit words (128 bits)
+#define EIP207_FLOW_HASH_ID_WORD_COUNT           4
+
+// Flag bitmask for the Flags field in the flow record,
+// see EIP207_Flow_OutputData_t
+#define EIP207_FLOW_FLAG_INBOUND    BIT_1
+
+// Place holder for device specific internal I/O data
+typedef struct
+{
+    // Pointer to the internal data storage to be allocated by the API user,
+    // EIP207_Flow_IOArea_ByteCount_Get() provides the size for the allocation
+    void * Data_p;
+
+} EIP207_Flow_IOArea_t;
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Error_t
+ *
+ * Status (error) code type returned by these API functions
+ * See each function "Return value" for details.
+ *
+ * EIP207_FLOW_NO_ERROR : successful completion of the call.
+ * EIP207_FLOW_RECORD_REMOVE_BUSY: flow record removal is ongoing
+ * EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR : not supported.
+ * EIP207_FLOW_ARGUMENT_ERROR :  invalid argument for a function parameter.
+ * EIP207_FLOW_BUSY_RETRY_LATER : device is busy.
+ * EIP207_FLOW_OUT_OF_MEMORY_ERROR : no more free entries in Hash Table to add
+ *                                   new record (or out of overflow buckets).
+ * EIP207_FLOW_ILLEGAL_IN_STATE : illegal state transition
+ */
+typedef enum
+{
+    EIP207_FLOW_NO_ERROR = 0,
+    EIP207_FLOW_RECORD_REMOVE_BUSY,
+    EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR,
+    EIP207_FLOW_ARGUMENT_ERROR,
+    EIP207_FLOW_INTERNAL_ERROR,
+    EIP207_FLOW_OUT_OF_MEMORY_ERROR,
+    EIP207_FLOW_ILLEGAL_IN_STATE
+} EIP207_Flow_Error_t;
+
+// Table/group size encoding in entries
+typedef enum
+{
+    EIP207_FLOW_HASH_TABLE_ENTRIES_32 = 0,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_64,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_128,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_256,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_512,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_1024,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_2048,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_4096,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_8192,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_16384,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_32768,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_65536,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_131072,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_262144,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_524288,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_1048576,
+    EIP207_FLOW_HASH_TABLE_ENTRIES_MAX = EIP207_FLOW_HASH_TABLE_ENTRIES_1048576
+} EIP207_Flow_HashTable_Entry_Count_t;
+
+// Flow hash ID
+typedef struct
+{
+    // 128-bit flow hash ID value
+    uint32_t Word32 [EIP207_FLOW_HASH_ID_WORD_COUNT];
+
+} EIP207_Flow_ID_t;
+
+// Physical (bus) address that can be used for DMA by the device
+typedef struct
+{
+    // 32-bit physical bus address
+    uint32_t Addr;
+
+    // upper 32-bit part of a 64-bit physical address
+    // Note: this value has to be provided only for 64-bit addresses,
+    // in this case Addr field provides the lower 32-bit part
+    // of the 64-bit address, for 32bit addresses this field is ignored,
+    // and should be set to 0.
+    uint32_t UpperAddr;
+
+} EIP207_Flow_Address_t;
+
+// This data structure represents the packet parameters (such as IP addresses
+// and ports) that select a particular flow.
+typedef struct
+{
+    // Bitwise or of zero or more EIP207_FLOW_SELECT_* flags
+    uint32_t  Flags;
+
+    // IPv4 (4 bytes) source address
+    uint8_t * SrcIp_p;
+
+    // IPv4 (4 bytes) destination address
+    uint8_t * DstIp_p;
+
+    // IP protocol (UDP, ESP) code as per RFC
+    uint8_t   IpProto;
+
+    // Source port for UDP
+    uint16_t  SrcPort;
+
+    // Destination port for UDP
+    uint16_t  DstPort;
+
+    // SPI in IPsec
+    uint32_t  SPI;
+
+    // Epoch in DTLS
+    uint16_t  Epoch;
+} EIP207_Flow_SelectorParams_t;
+
+// Flow record input data required for the flow record creation
+typedef struct
+{
+    // Bitwise of zero or more EIP207_FLOW_FLAG_* flags, see above
+    uint32_t Flags;
+
+    // Flow record hash ID
+    EIP207_Flow_ID_t HashID;
+
+    // Physical (DMA/bus) address of the transform record
+    EIP207_Flow_Address_t Xform_DMA_Addr;
+
+    // Software flow record reference
+    uint32_t SW_FR_Reference;
+
+    // Transform record type, true - large, false - small
+    bool fLarge;
+
+} EIP207_Flow_FR_InputData_t;
+
+// Transform record input data required for the Transform record creation
+typedef struct
+{
+    // Transform record hash ID
+    EIP207_Flow_ID_t HashID;
+
+    // Transform record type, true - large, false - small
+    bool fLarge;
+
+} EIP207_Flow_TR_InputData_t;
+
+// Data that can be read from flow record (flow output data)
+// This data is written in the flow record by the firmware running
+// inside the classification engine
+typedef struct
+{
+    // The time stamp of the last record access, in engine clock cycles
+    uint32_t LastTimeLo;   // Low 32-bits
+    uint32_t LastTimeHi;   // High 32-bits
+
+    // Number of packets processed for this flow record, 32-bit integer
+    uint32_t PacketsCounter;
+
+    // Number of octets processed for this flow record, 64-bit integer
+    uint32_t OctetsCounterLo;  // Low 32-bits
+    uint32_t OctetsCounterHi;  // High 32-bits
+
+} EIP207_Flow_FR_OutputData_t;
+
+// Data that can be read from transform record (output data)
+// This data is written in the transform record by the firmware running
+// inside the classification engine
+typedef struct
+{
+    // The time stamp of the last record access, in engine clock cycles
+    uint32_t LastTimeLo;   // Low 32-bits
+    uint32_t LastTimeHi;   // High 32-bits
+
+    // 32-bit sequence number of outbound transform
+    uint32_t SequenceNumber;
+
+    // Number of packets processed for this transform record, 32-bit integer
+    uint32_t PacketsCounter;
+
+    // Number of octets processed for this transform record, 64-bit integer
+    uint32_t OctetsCounterLo;   // Low 32-bits
+    uint32_t OctetsCounterHi;   // High 32-bits
+
+} EIP207_Flow_TR_OutputData_t;
+
+// Hash table (HT) initialization structure
+typedef struct
+{
+    // Handle for the DMA resource describing the DMA-safe buffer for the Hash
+    // Table. One HT entry is one hash bucket.
+    DMAResource_Handle_t HT_DMA_Handle;
+
+    // HT DMA (physical) address
+    EIP207_Flow_Address_t * HT_DMA_Address_p;
+
+    // HT maximum table size N in HW-specific encoding
+    EIP207_Flow_HashTable_Entry_Count_t HT_TableSize;
+
+    // Descriptor Table (DT) host address,
+    // this buffer does not have to be DMA-safe
+    void * DT_p;
+
+    // DT maximum entry count (size), one entry is one descriptor
+    unsigned int DT_EntryCount;
+
+} EIP207_Flow_HT_t;
+
+// General record descriptor
+typedef struct
+{
+    // Record DMA Resource handle
+    DMAResource_Handle_t DMA_Handle;
+
+    // Record DMA (bus/physical) address
+    EIP207_Flow_Address_t DMA_Addr;
+
+    // Pointer to internal data structure for internal use,
+    // the API user must not write or read this field
+    void * InternalData_p;
+
+} EIP207_Flow_Dscr_t;
+
+// Flow record data structure,
+// Note: while allocating this place holder for this data structure its size
+//       must be obtained via the EIP207_Flow_FR_Dscr_ByteCount_Get() function
+typedef EIP207_Flow_Dscr_t EIP207_Flow_FR_Dscr_t;
+
+// Transform record data structure
+// Note: while allocating this place holder for this data structure its size
+//       must be obtained via the EIP207_Flow_TR_Dscr_ByteCount_Get() function
+typedef EIP207_Flow_Dscr_t EIP207_Flow_TR_Dscr_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_IOArea_ByteCount_Get
+ *
+ * This function returns the required size of the I/O Area (in bytes).
+ */
+unsigned int
+EIP207_Flow_IOArea_ByteCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HT_Entry_WordCount_Get
+ *
+ * This function returns the required size of one Hash Table entry
+ * (in 32-bit words).
+ *
+ * This function can be used for the memory allocation for the HT.
+ */
+unsigned int
+EIP207_Flow_HT_Entry_WordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_ByteCount_Get
+ *
+ * This function returns the required size of one HT Entry Descriptor
+ * (in bytes).
+ *
+ * This function can be used for the memory allocation for the DT.
+ */
+unsigned int
+EIP207_Flow_HTE_Dscr_ByteCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Dscr_ByteCount_Get
+ *
+ * This function returns the required size of one Flow Record Descriptor
+ * (in bytes).
+ *
+ * This function can be used for the memory allocation for the Flow Record
+ * Descriptor.
+ */
+unsigned int
+EIP207_Flow_FR_Dscr_ByteCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Dscr_ByteCount_Get
+ *
+ * This function returns the required size of one Transform Record Descriptor
+ * (in bytes).
+ *
+ * This function can be used for the memory allocation for the Transform Record
+ * Descriptor.
+ */
+unsigned int
+EIP207_Flow_TR_Dscr_ByteCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Record_Dummy_Addr_Get
+ *
+ * This function returns the dummy record address.
+ */
+unsigned int
+EIP207_Flow_Record_Dummy_Addr_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Init
+ *
+ * This function performs the initialization of the EIP-207 Flow Control SW
+ * interface and transits the API to the "Flow Control Initialized" state for
+ * the requested classification device.
+ *
+ * This function returns the EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Flow Control Driver Library configuration
+ * and the used EIP-207 HW capabilities.
+ *
+ * Note: This function should be called either after the HW Reset or
+ *       after the Global SW Reset.
+ *       This function should be called for the Classification device
+ *       identified by the Device parameter before any other functions of
+ *       this API (except for EIP207_Flow_ID_Compute()) can be called
+ *       for the IO Area returned for this Device.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area
+ *     for the Classification device identified by the Device parameter.
+ *     The memory must be allocated by the caller before invoking
+ *     this function.
+ *
+ * Device (input)
+ *     Handle for the EIP-207 Flow Control device instance returned
+ *     by Device_Find().
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Init(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HashTable_Install
+ *
+ * This function installs the Hash Table as well as the Descriptor
+ * Table and transits the API to the "Flow Control Enabled" state for
+ * the classification device identified by the IO Area.
+ *
+ * Note: This function should be called after the EIP207_Flow_Init()
+ *       function is called for the required Classification device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table that must be set up.
+ *
+ * HT_p (Input)
+ *     Pointer for the Hash Table (HT) identified by the HashTableId.
+ *     One HT entry is one hash bucket.
+ *
+ * fLookupCached (input)
+ *     Set to true to enable the FLUE cache
+ *     (improves performance)
+ *
+ * fReset (input)
+ *     Set to true to re-initialize the HT.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_HashTable_Install(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_HT_t * HT_p,
+        bool fLookupCached,
+        bool fReset);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_RC_BaseAddr_Set
+ *
+ * Set the FLUE Record Cache base address for the records.
+ *
+ * Note: This function should be called after the EIP207_Flow_Init()
+ *       function is called for the required Classification device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the Hash Table for which the Record Cache base address
+ *     must be set up.
+ *
+ * FlowBaseAddr (input)
+ *     Base address of the Flow Record Cache. All the flow records must be
+ *     allocated within 4GB address region from this FlowBaseAddr base address.
+ *
+ * TransformBaseAddr (input)
+ *     Base address of the Transform Record Cache. All the transform records
+ *     must be allocated within 4GB address region from this TransformBaseAddr
+ *     base address.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_RC_BaseAddr_Set(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_Address_t * const FlowBaseAddr,
+        const EIP207_Flow_Address_t * const TransformBaseAddr);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_ID_Compute
+ *
+ * This function performs the flow hash ID computation.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table.
+ *
+ * SelectorParams_p (input)
+ *     Pointer to the data structure that contain parameters that should be
+ *     used for the flow ID computation
+ *
+ * FlowID (output)
+ *     Pointer to the data structure where the calculated flow hash ID will
+ *     be stored
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_ID_Compute(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_SelectorParams_t * const SelectorParams_p,
+        EIP207_Flow_ID_t * const FlowID);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_WordCount_Get
+ *
+ * This function returns the required size of one Flow Record
+ * (in 32-bit words).
+ */
+unsigned int
+EIP207_Flow_FR_WordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Add
+ *
+ * This function adds the provided flow record to the Flow Hash Table
+ * so that the classification device can look it up.
+ *
+ * This function returns the EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Flow Control Driver Library configuration
+ * and the used EIP-207 HW capabilities.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be added.
+ *
+ * FR_Dscr_p (input)
+ *     Pointer to the data structure that describes the flow record to be added.
+ *     This descriptor must exist along with the flow record it describes until
+ *     that flow record is removed by the EIP207_Flow_Record_Remove() function.
+ *     The flow descriptor pointer cannot be 0.
+ *
+ * FlowInData_p (input)
+ *     Pointer to the data structure that contains the input data that will
+ *     be used for filling in the flow record. The buffer holding this data
+ *     structure can be freed after this function returns.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Add(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+        const EIP207_Flow_FR_InputData_t * const FlowInData_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Read
+ *
+ * This function reads data from the provided flow record.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be removed from.
+ *
+ * FR_Dscr_p (output)
+ *     Pointer to the data structure that describes the flow record
+ *     to be read. Cannot be 0.
+ *
+ * FlowData_p (output)
+ *     Pointer to the data structure where the read flow data will be stored.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+        EIP207_Flow_FR_OutputData_t * const FlowData_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_WordCount_Get
+ *
+ * This function returns the required size of one Transform Record
+ * (in 32-bit words).
+ */
+unsigned int
+EIP207_Flow_TR_WordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Read
+ *
+ * This function reads output data from the provided transform record.
+ *
+ * IOArea_p (input)
+ *     Pointer to the IO Area of the required Classification device.
+ *
+ * HashTableId (input)
+ *     Index of the flow hash table where the flow record must be removed from.
+ *
+ * TR_Dscr_p (input)
+ *     Pointer to the transform record descriptor. The transform record
+ *     descriptor is only used during this function execution.
+ *     It can be discarded after this function returns.
+ *
+ * XformData_p (output)
+ *     Pointer to the data structure where the read transform data will
+ *     be stored.
+ *
+ * Return value
+ *     EIP207_FLOW_NO_ERROR
+ *     EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_FLOW_ARGUMENT_ERROR
+ *     EIP207_FLOW_ILLEGAL_IN_STATE
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_TR_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        EIP207_Flow_TR_OutputData_t * const XformData_p);
+
+
+#endif /* EIP207_FLOW_GENERIC_H_ */
+
+
+/* end of file eip207_flow_generic.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hte_dscr_dtl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hte_dscr_dtl.h
new file mode 100644
index 0000000..e992893
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hte_dscr_dtl.h
@@ -0,0 +1,279 @@
+/* eip207_flow_hte_dscr_dtl.h
+ *
+ * Helper functions for operations with the HTE Descriptor DTL,
+ * interface
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_HTE_DSCR_DTL_H_
+#define EIP207_FLOW_HTE_DSCR_DTL_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Record offset mask values
+#define EIP207_FLOW_HTE_REC_OFFSET_1        0x01
+#define EIP207_FLOW_HTE_REC_OFFSET_2        0x02
+#define EIP207_FLOW_HTE_REC_OFFSET_3        0x04
+#define EIP207_FLOW_HTE_REC_OFFSET_ALL      MASK_3_BITS
+
+// Type of records for lookup by FLUE
+typedef enum
+{
+    EIP207_FLOW_REC_INVALID = 0,
+    EIP207_FLOW_REC_FLOW,
+    EIP207_FLOW_REC_TRANSFORM_SMALL,
+    EIP207_FLOW_REC_TRANSFORM_LARGE
+} EIP207_Flow_Record_Type_t;
+
+// Record states
+typedef enum
+{
+    EIP207_FLOW_REC_STATE_INSTALLED = 1,
+    EIP207_FLOW_REC_STATE_REMOVED
+} EIP207_Flow_Rec_State_t;
+
+// HTE descriptor list
+typedef struct
+{
+    // Pointer to the next descriptor in the chain
+    void * NextDscr_p;
+
+    // Pointer to the previous descriptor in the chain
+    void * PrevDscr_p;
+
+} EIP207_Flow_HTE_Dscr_List_t;
+
+// Hash Table Entry (HTE) descriptor
+typedef struct
+{
+    // Hash Bucket byte offset from the Hash Table base address
+    uint32_t Bucket_ByteOffset;
+
+    // Record reference count,
+    // 0 when Hash Bucket refers to no records for lookup
+    unsigned int RecordCount;
+
+    // True when descriptor is for an overflow Hash Bucket
+    bool fOverflowBucket;
+
+    // Mask for used record offsets fields in the Hash Bucket,
+    // see EIP207_FLOW_HTE_REC_OFFSET_*
+    uint32_t UsedRecOffsMask;
+
+    // List of HTE descriptors, either the free list of unused descriptors or
+    // the hash bucket overflow chain
+    EIP207_Flow_HTE_Dscr_List_t List;
+
+} EIP207_Flow_HTE_Dscr_t;
+
+// Record data
+typedef struct
+{
+    // Record type
+    EIP207_Flow_Record_Type_t Type;
+
+    // Host address (pointer) for the HTE descriptor associated with the record
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p;
+
+    // Slot number in the Hash Bucket descriptor used by this record
+    unsigned int Slot;
+
+} EIP207_Flow_HTE_Dscr_RecData_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Prev_Get
+ *
+ * Gets the previous HTE descriptor for the provided one
+ * in the descriptor list
+ */
+static inline EIP207_Flow_HTE_Dscr_t *
+EIP207_Flow_HTE_Dscr_List_Prev_Get(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p)
+{
+    if (HTE_Dscr_p != NULL)
+    {
+        EIP207_Flow_HTE_Dscr_List_t * List_p;
+
+        List_p = &HTE_Dscr_p->List;
+
+        return List_p->PrevDscr_p;
+    }
+    else
+        return NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Prev_Set
+ *
+ * Sets the previous HTE descriptor for the provided one
+ * in the descriptor list
+ */
+static inline void
+EIP207_Flow_HTE_Dscr_List_Prev_Set(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p,
+        EIP207_Flow_HTE_Dscr_t * const Prev_HTE_Dscr_p)
+{
+    if (HTE_Dscr_p != NULL)
+    {
+        EIP207_Flow_HTE_Dscr_List_t * List_p;
+
+        List_p = &HTE_Dscr_p->List;
+
+        List_p->PrevDscr_p = Prev_HTE_Dscr_p;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Next_Get
+ *
+ * Gets the next HTE descriptor for the provided one
+ * in the descriptor list
+ */
+static inline EIP207_Flow_HTE_Dscr_t *
+EIP207_Flow_HTE_Dscr_List_Next_Get(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p)
+{
+    if (HTE_Dscr_p != NULL)
+    {
+        EIP207_Flow_HTE_Dscr_List_t * List_p;
+
+        List_p = &HTE_Dscr_p->List;
+
+        return List_p->NextDscr_p;
+    }
+    else
+        return NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Next_Set
+ *
+ * Sets the next HTE descriptor for the provided one
+ * in the descriptor list
+ */
+static inline void
+EIP207_Flow_HTE_Dscr_List_Next_Set(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p,
+        EIP207_Flow_HTE_Dscr_t * const Next_HTE_Dscr_p)
+{
+    if (HTE_Dscr_p)
+    {
+        EIP207_Flow_HTE_Dscr_List_t * List_p;
+
+        List_p = &HTE_Dscr_p->List;
+
+        List_p->NextDscr_p = Next_HTE_Dscr_p;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Remove
+ *
+ * Remove HTE descriptor from the list it's on
+ */
+static inline void
+EIP207_Flow_HTE_Dscr_List_Remove(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p)
+{
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Prev_p;
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p;
+
+    // Update the list
+    HTE_Dscr_Prev_p =
+               EIP207_Flow_HTE_Dscr_List_Prev_Get(HTE_Dscr_p);
+
+    HTE_Dscr_Next_p =
+               EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+
+    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_Prev_p,
+                                       HTE_Dscr_Next_p);
+
+    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_Next_p,
+                                       HTE_Dscr_Prev_p);
+
+    // Update the HTE descriptor
+    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p, NULL);
+    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p, NULL);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_List_Insert
+ *
+ * Insert HTE descriptor to the list using HTE_Dscr_Prev_p as the previous
+ * descriptor
+ */
+static inline void
+EIP207_Flow_HTE_Dscr_List_Insert(
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_Prev_p,
+        EIP207_Flow_HTE_Dscr_t * const HTE_Dscr_p)
+{
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p;
+
+    // Update the list, get the next HTE descriptor for HTE_Dscr_Prev_p
+    HTE_Dscr_Next_p =
+               EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_Prev_p);
+
+    // Update the HTE_Dscr_Prev_p descriptor
+    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_Prev_p,
+                                       HTE_Dscr_p);
+
+    // Update the HTE_Dscr_Next_p descriptor
+    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_Next_p,
+                                       HTE_Dscr_p);
+
+    // Update the HTE descriptor
+    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p, HTE_Dscr_Next_p);
+    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p, HTE_Dscr_Prev_p);
+}
+
+
+#endif /* EIP207_FLOW_HTE_DSCR_DTL_H_ */
+
+
+/* end of file eip207_flow_hte_dscr_dtl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface.h
new file mode 100644
index 0000000..b4d5e0e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface.h
@@ -0,0 +1,68 @@
+/* eip207_flow_hw_interface.h
+ *
+ * EIP-207 Flow HW interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_HW_INTERFACE_H_
+#define EIP207_FLOW_HW_INTERFACE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint16_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-207 HIA registers
+ *****************************************************************************/
+
+// EIP-207c FLUE EIP number (0xCF) and complement (0x30)
+#define EIP207_FLUE_SIGNATURE           ((uint16_t)0x30CF)
+
+#define EIP207_REG_OFFS                 4
+
+
+// EIP-207 Flow HW interface extensions
+#include "eip207_flow_hw_interface_ext.h"
+
+
+#endif /* EIP207_FLOW_HW_INTERFACE_H_ */
+
+
+/* end of file eip207_flow_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface_ext.h
new file mode 100644
index 0000000..cc08805
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_hw_interface_ext.h
@@ -0,0 +1,156 @@
+/* eip207_flow_hw_interface_ext.h
+ *
+ * EIP-207 Flow HW interface extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_HW_INTERFACE_EXT_H_
+#define EIP207_FLOW_HW_INTERFACE_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// One entry size (in 32-bit words) in the Hash Table
+// One HT entry = one hash bucket, 16 32-bit words
+#define EIP207_FLOW_HT_ENTRY_WORD_COUNT          16
+
+// Maximum number of records one Hash Bucket can refer to
+#define EIP207_FLOW_HTE_BKT_NOF_REC_MAX          3
+
+#define EIP207_FLOW_RECORD_ADDRESS_TYPE_BITS     MASK_2_BITS
+#define EIP207_FLOW_RECORD_DUMMY_ADDRESS         0
+#define EIP207_FLOW_RECORD_FR_ADDRESS            1
+#define EIP207_FLOW_RECORD_TR_ADDRESS            2
+#define EIP207_FLOW_RECORD_TR_LARGE_ADDRESS      3
+
+// Hash ID fields offsets in the hash bucket
+#define EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET     0
+#define EIP207_FLOW_HB_HASH_ID_2_WORD_OFFSET                                 \
+                                   (EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET +   \
+                                      EIP207_FLOW_HASH_ID_WORD_COUNT)
+#define EIP207_FLOW_HB_HASH_ID_3_WORD_OFFSET                                 \
+                                   (EIP207_FLOW_HB_HASH_ID_2_WORD_OFFSET +   \
+                                      EIP207_FLOW_HASH_ID_WORD_COUNT)
+#define EIP207_FLOW_HB_REC_1_WORD_OFFSET                                     \
+                                   (EIP207_FLOW_HB_HASH_ID_3_WORD_OFFSET +   \
+                                      EIP207_FLOW_HASH_ID_WORD_COUNT)
+#define EIP207_FLOW_HB_REC_2_WORD_OFFSET                                     \
+                                   (EIP207_FLOW_HB_REC_1_WORD_OFFSET + 1)
+#define EIP207_FLOW_HB_REC_3_WORD_OFFSET                                     \
+                                   (EIP207_FLOW_HB_REC_2_WORD_OFFSET + 1)
+#define EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET                               \
+                                   (EIP207_FLOW_HB_REC_3_WORD_OFFSET + 1)
+
+// Read/Write register constants
+
+
+/*****************************************************************************
+ * Byte offsets of the EIP-207 FLUE and FHASH registers
+ *****************************************************************************/
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) CACHEBASE registers
+#define EIP207_FLUE_FHT_REG_CACHEBASE_LO(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_FHT1_REG_BASE + \
+                                        (0x00 * EIP207_REG_OFFS))
+
+#define EIP207_FLUE_FHT_REG_CACHEBASE_HI(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_FHT1_REG_BASE + \
+                                        (0x01 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) HASHBASE registers
+#define EIP207_FLUE_FHT_REG_HASHBASE_LO(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_FHT2_REG_BASE + \
+                                        (0x00 * EIP207_REG_OFFS))
+
+#define EIP207_FLUE_FHT_REG_HASHBASE_HI(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_FHT2_REG_BASE + \
+                                        (0x01 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support,
+// Flow Look-Up Engine (FLUE) SIZE register
+#define EIP207_FLUE_FHT_REG_SIZE(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_FHT3_REG_BASE + \
+                                        (0x00 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support, options and version registers
+#define EIP207_FLUE_FHT_REG_OPTIONS  \
+                                     (EIP207_FLUE_OPTVER_REG_BASE + \
+                                       (0x00 * EIP207_REG_OFFS))
+
+#define EIP207_FLUE_FHT_REG_VERSION  \
+                                     (EIP207_FLUE_OPTVER_REG_BASE + \
+                                       (0x01 * EIP207_REG_OFFS))
+
+
+// EIP-207s Classification Support, Flow Hash Engine (FHASH) registers
+#define EIP207_FHASH_REG_IV_0(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_HASH_REG_BASE + \
+                                        (0x00 * EIP207_REG_OFFS))
+
+#define EIP207_FHASH_REG_IV_1(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_HASH_REG_BASE + \
+                                        (0x01 * EIP207_REG_OFFS))
+
+#define EIP207_FHASH_REG_IV_2(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_HASH_REG_BASE + \
+                                        (0x02 * EIP207_REG_OFFS))
+
+#define EIP207_FHASH_REG_IV_3(f)  \
+                                     (EIP207_FLUE_FHT_REG_MAP_SIZE * f + \
+                                       EIP207_FLUE_HASH_REG_BASE + \
+                                        (0x03 * EIP207_REG_OFFS))
+
+
+// Register default value
+#define EIP207_FLUE_REG_CACHEBASE_LO_DEFAULT   0x00000000
+#define EIP207_FLUE_REG_CACHEBASE_HI_DEFAULT   0x00000000
+#define EIP207_FLUE_REG_HASHBASE_LO_DEFAULT    0x00000000
+#define EIP207_FLUE_REG_HASHBASE_HI_DEFAULT    0x00000000
+#define EIP207_FLUE_REG_SIZE_DEFAULT           0x00000000
+#define EIP207_FLUE_REG_IV_DEFAULT             0x00000000
+
+
+#endif /* EIP207_FLOW_HW_INTERFACE_EXT_H_ */
+
+
+/* end of file eip207_flow_hw_interface_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_internal.h
new file mode 100644
index 0000000..291215d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_internal.h
@@ -0,0 +1,191 @@
+/* eip207_flow_internal.h
+ *
+ * EIP-207 Flow Control Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_INTERNAL_H_
+#define EIP207_FLOW_INTERNAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Flow Control Driver Library Generic interface
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLOW_DSCR_DUMMY_ADDRESS_BYTE             0
+
+#define EIP207_FLOW_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS   2
+
+#define IOAREA(_p) ((volatile EIP207_Flow_True_IOArea_t *)_p)
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+#define EIP207_FLOW_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#define EIP207_FLOW_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#define EIP207_FLOW_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#define EIP207_FLOW_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#else
+/* EIP207_FLOW_STRICT_ARGS undefined */
+#define EIP207_FLOW_CHECK_POINTER(_p)
+#define EIP207_FLOW_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP207_FLOW_CHECK_INT_ATLEAST(_i, _min)
+#define EIP207_FLOW_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP207_FLOW_STRICT_ARGS */
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+// EIP-207 Flow Control API States
+typedef enum
+{
+    EIP207_FLOW_STATE_INITIALIZED  = 1,
+    EIP207_FLOW_STATE_ENABLED,
+    EIP207_FLOW_STATE_INSTALLED,
+    EIP207_FLOW_STATE_FATAL_ERROR
+} EIP207_Flow_State_t;
+#endif // EIP207_FLOW_DEBUG_FSM
+
+// Physical (bus) address that can be used for DMA by the device
+typedef struct
+{
+    // 32-bit physical bus address
+    uint32_t Addr;
+
+    // upper 32-bit part of a 64-bit physical address
+    // Note: this value has to be provided only for 64-bit addresses,
+    // in this case Addr field provides the lower 32-bit part
+    // of the 64-bit address, for 32-bit addresses this field is ignored,
+    // and should be set to 0.
+    uint32_t UpperAddr;
+
+} EIP207_Flow_Internal_Address_t;
+
+// Hash Table parameters
+typedef struct
+{
+    // DMA Resource handle for the Hash Table (HT)
+    DMAResource_Handle_t HT_DMA_Handle;
+
+    // Pointer to the Flow Descriptor Table (DT)
+    void * DT_p;
+
+    // DMA (physical) base address for records for lookup
+    EIP207_Flow_Internal_Address_t BaseAddr;
+
+    // HT table size (in EIP207_Flow_HashTable_Entry_Count_t units)
+    unsigned int HT_TableSize;
+
+    // Pointer to List head of free HTE descriptors for overflow hash buckets
+    void * FreeList_Head_p;
+
+    // True when FLUEC is enabled
+    bool fLookupCached;
+
+} EIP207_Flow_HT_Params_t;
+
+// I/O Area, used internally
+typedef struct
+{
+    // Classification engine state
+    uint32_t State;
+
+    // Device handle representing the Classification engine
+    Device_Handle_t Device;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    unsigned int Rec_InstalledCounter;
+#endif
+
+    // Flow Hash Table parameters
+    EIP207_Flow_HT_Params_t  HT_Params [EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE];
+
+} EIP207_Flow_True_IOArea_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Internal_Read64
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Internal_Read64(
+        const DMAResource_Handle_t Handle,
+        const unsigned int Value64_WordOffsetLo,
+        const unsigned int Value64_WordOffsetHi,
+        uint32_t * const Value64_Lo,
+        uint32_t * const Value64_Hi);
+
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_State_Set
+ *
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_State_Set(
+        EIP207_Flow_State_t * const CurrentState,
+        const EIP207_Flow_State_t NewState);
+#endif // EIP207_FLOW_DEBUG_FSM
+
+
+#endif /* EIP207_FLOW_INTERNAL_H_ */
+
+
+/* end of file eip207_flow_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0.h
new file mode 100644
index 0000000..fe25c77
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0.h
@@ -0,0 +1,161 @@
+/* eip207_flow_level0.h
+ *
+ * EIP-207 Flow Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_LEVEL0_H_
+#define EIP207_FLOW_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// EIP-207 Flow HW interface
+#include "eip207_flow_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 Global Register Write/Read Functions
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Read32
+ *
+ * This routine writes to a Register location in the EIP-207.
+ */
+static inline uint32_t
+EIP207_Flow_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Write32
+ *
+ * This routine writes to a Register location in the EIP-207.
+ */
+static inline void
+EIP207_Flow_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+
+#ifdef EIP207_FLOW_CLUSTERED_WRITES_DISABLE
+    // Prevent clustered write operations, break them with a read operation
+    // Note: Reading the EIP207_CS_REG_VERSION register has no side effects!
+    EIP207_Flow_Read32(Device, EIP207_CS_REG_VERSION);
+#endif
+}
+
+
+static inline bool
+EIP207_FLUE_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP207_FLUE_SIGNATURE);
+}
+
+
+static inline void
+EIP207_FLUE_HASHBASE_LO_WR(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        const uint32_t Addr32Lo)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_HASHBASE_LO_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)Addr32Lo) & (~MASK_2_BITS)));
+
+    EIP207_Flow_Write32(Device,
+                        EIP207_FLUE_FHT_REG_HASHBASE_LO(HashTableNr),
+                        RegVal);
+}
+
+
+static inline void
+EIP207_FLUE_HASHBASE_HI_WR(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        const uint32_t Addr32Hi)
+{
+    EIP207_Flow_Write32(Device,
+                        EIP207_FLUE_FHT_REG_HASHBASE_HI(HashTableNr),
+                        Addr32Hi);
+}
+
+
+static inline void
+EIP207_FHASH_IV_RD(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        uint32_t * const IV_0,
+        uint32_t * const IV_1,
+        uint32_t * const IV_2,
+        uint32_t * const IV_3)
+{
+    *IV_0 = EIP207_Flow_Read32(Device, EIP207_FHASH_REG_IV_0(HashTableNr));
+    *IV_1 = EIP207_Flow_Read32(Device, EIP207_FHASH_REG_IV_1(HashTableNr));
+    *IV_2 = EIP207_Flow_Read32(Device, EIP207_FHASH_REG_IV_2(HashTableNr));
+    *IV_3 = EIP207_Flow_Read32(Device, EIP207_FHASH_REG_IV_3(HashTableNr));
+}
+
+
+// EIP-207 Flow Level0 interface extensions
+#include "eip207_flow_level0_ext.h"
+
+
+#endif /* EIP207_FLOW_LEVEL0_H_ */
+
+
+/* end of file eip207_flow_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0_ext.h
new file mode 100644
index 0000000..160de37
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flow_level0_ext.h
@@ -0,0 +1,105 @@
+/* eip207_flow_level0_ext.h
+ *
+ * EIP-207 Flow Level0 Internal interface extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLOW_LEVEL0_EXT_H_
+#define EIP207_FLOW_LEVEL0_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 Flow Functions
+ *
+ */
+
+static inline void
+EIP207_FLUE_CACHEBASE_LO_WR(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        const uint32_t Addr32Lo)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_CACHEBASE_LO_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)Addr32Lo) & (~MASK_2_BITS)));
+
+    EIP207_Flow_Write32(Device,
+                        EIP207_FLUE_FHT_REG_CACHEBASE_LO(HashTableNr),
+                        RegVal);
+}
+
+
+static inline void
+EIP207_FLUE_CACHEBASE_HI_WR(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        const uint32_t Addr32Hi)
+{
+    EIP207_Flow_Write32(Device,
+                        EIP207_FLUE_FHT_REG_CACHEBASE_HI(HashTableNr),
+                        Addr32Hi);
+}
+
+
+static inline void
+EIP207_FLUE_SIZE_UPDATE(
+        const Device_Handle_t Device,
+        const unsigned int HashTableNr,
+        const uint8_t TableSize)
+{
+    uint32_t RegVal =
+                EIP207_Flow_Read32(Device,
+                                   EIP207_FLUE_FHT_REG_SIZE(HashTableNr));
+
+    RegVal &= (~(MASK_4_BITS << 4));
+    RegVal |=
+          (uint32_t)((((uint32_t)TableSize) & MASK_4_BITS) << 4);
+
+    EIP207_Flow_Write32(Device,
+                        EIP207_FLUE_FHT_REG_SIZE(HashTableNr),
+                        RegVal);
+}
+
+
+#endif /* EIP207_FLOW_LEVEL0_EXT_H_ */
+
+
+/* end of file eip207_flow_level0_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flue.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flue.h
new file mode 100644
index 0000000..477d6da
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_flue.h
@@ -0,0 +1,82 @@
+/* eip207_flue.h
+ *
+ * EIP-207s Flow Look-Up Engine (FLUE) interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLUE_H_
+#define EIP207_FLUE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-207 Global Control Init API
+#include "eip207_global_init.h"         // EIP207_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Init
+ */
+void
+EIP207_FLUE_Init(
+        const Device_Handle_t Device,
+        const unsigned int HashTableId,
+        const EIP207_Global_FLUEConfig_t * const FLUEConf_p,
+        const bool fARC4Present,
+        const bool fLookupCachePresent);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Status_Get
+ */
+void
+EIP207_FLUE_Status_Get(
+        const Device_Handle_t Device,
+        EIP207_Global_FLUE_Status_t * const FLUE_Status_p);
+
+
+/* end of file eip207_flue.h */
+
+
+#endif /* EIP207_FLUE_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec.h
new file mode 100644
index 0000000..f39d4ac
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec.h
@@ -0,0 +1,83 @@
+/* eip207_fluec.h
+ *
+ * EIP-207 Flow Look-Up Engine Cache (FLUEC) interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLUEC_H_
+#define EIP207_FLUEC_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint8_t, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUEC_Invalidate
+ *
+ * This function invalidates a cached lookup result in the lookup cache
+ * based on the flow ID.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * InvTable (input)
+ *      Lookup table where the invalidation must be done.
+ *
+ * FlowID_Wn (input)
+ *      32-bit word n of the 128-bit Flow hash ID.
+ *
+ * Return code
+ *      None
+ */
+void
+EIP207_FLUEC_Invalidate(
+        const Device_Handle_t Device,
+        const uint8_t InvTable,
+        const uint32_t FlowID_W0,
+        const uint32_t FlowID_W1,
+        const uint32_t FlowID_W2,
+        const uint32_t FlowID_W3);
+
+
+/* end of file eip207_fluec.h */
+
+
+#endif /* EIP207_FLUEC_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec_level0.h
new file mode 100644
index 0000000..04b9082
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_fluec_level0.h
@@ -0,0 +1,83 @@
+/* eip207_fluec_level0.h
+ *
+ * EIP-207 Flow Look-Up Engine Cache (FLUEC) Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_FLUEC_LEVEL0_H_
+#define EIP207_FLUEC_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t,
+                                // IDENTIFIER_NOT_USED
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 FLUEC Functions
+ *
+ */
+
+static inline void
+EIP207_FLUEC_CTRL_WR(
+        const Device_Handle_t Device,
+        const bool fSWReset,
+        const bool fDelayMemXS,
+        const uint8_t TableSize,
+        const uint8_t GroupSize,
+        const uint8_t CacheChain)
+{
+    // Not implemented
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(fSWReset);
+    IDENTIFIER_NOT_USED(fDelayMemXS);
+    IDENTIFIER_NOT_USED(TableSize);
+    IDENTIFIER_NOT_USED(GroupSize);
+    IDENTIFIER_NOT_USED(CacheChain);
+}
+
+
+#endif /* EIP207_FLUEC_LEVEL0_H_ */
+
+
+/* end of file eip207_fluec_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_config.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_config.h
new file mode 100644
index 0000000..f11d866
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_config.h
@@ -0,0 +1,141 @@
+/* eip207_global_config.h
+ *
+ * EIP-207 Global Control Driver Library
+ * Configuration Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_GLOBAL_CONFIG_H_
+#define EIP207_GLOBAL_CONFIG_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // bool
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// Data type for firmware config
+#include "eip207_global_init.h"
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP207_ICE_REG_SCRATCH_RAM
+
+// EIP-207c Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // FIRMWARE_EIP207_CS_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*--------------------- -------------------------------------------------------
+ * EIP207_Global_Firmware_Configure
+ */
+static inline void
+EIP207_Global_Firmware_Configure(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        const EIP207_Firmware_Config_t * const FWConfig_p)
+{
+    unsigned int ByteOffset;
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_DTLS_HDR_SIZE_BYTE_OFFSET
+    uint32_t Value;
+#endif
+    // Set input and output token format (with or without meta-data)
+    ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_TOKEN_FORMAT_BYTE_OFFSET;
+
+    EIP207_Write32(Device,
+                   EIP207_ICE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                   FWConfig_p->fTokenExtensionsEnable ? 1 : 0);
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_DTLS_HDR_SIZE_BYTE_OFFSET
+    ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_DTLS_HDR_SIZE_BYTE_OFFSET;
+    Value = FWConfig_p->DTLSRecordHeaderAlign;
+    if (FWConfig_p->fDTLSDeferCCS)
+        Value |= BIT_15;
+    if (FWConfig_p->fDTLSDeferAlert)
+        Value |= BIT_13;
+    if (FWConfig_p->fDTLSDeferHandshake)
+        Value |= BIT_13;
+    if (FWConfig_p->fDTLSDeferAppData)
+        Value |= BIT_12;
+    if (FWConfig_p->fDTLSDeferCAPWAP)
+        Value |= BIT_11;
+    EIP207_Write32(Device,
+                   EIP207_ICE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                   Value);
+#endif
+#ifdef EIP207_OCE_REG_SCRATCH_RAM // Test if we have this scratch RAM.
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_PKTID_BYTE_OFFSET
+        ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_PKTID_BYTE_OFFSET;
+        EIP207_Write32(Device,
+                       EIP207_OCE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                       FWConfig_p->fIncrementPktID ?
+                       FWConfig_p->PktID | BIT_16 :
+                       0);
+#endif
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_ECN_CONTROL_BYTE_OFFSET
+        ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_ECN_CONTROL_BYTE_OFFSET;
+        EIP207_Write32(Device,
+                       EIP207_OCE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                       FWConfig_p->ECNControl);
+#endif
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_REDIR_BYTE_OFFSET
+        ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_REDIR_BYTE_OFFSET;
+        EIP207_Write32(Device,
+                       EIP207_OCE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                       FWConfig_p->RedirRing |
+                       (FWConfig_p->fRedirRingEnable << 16) |
+                       (FWConfig_p->fAlwaysRedirect << 17));
+#endif
+#endif
+#ifdef FIRMWARE_EIP207_CS_ADMIN_RAM_REDIR_BYTE_OFFSET
+        ByteOffset = FIRMWARE_EIP207_CS_ADMIN_RAM_REDIR_BYTE_OFFSET;
+        EIP207_Write32(Device,
+                       EIP207_ICE_REG_SCRATCH_RAM(CE_Number) + ByteOffset,
+                       FWConfig_p->TransformRedirEnable);
+#endif
+}
+
+
+#endif // EIP207_GLOBAL_CONFIG_H_
+
+
+/* end of file eip207_global_config.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_init.h
new file mode 100644
index 0000000..1ba9783
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_global_init.h
@@ -0,0 +1,720 @@
+/* eip207_global_init.h
+ *
+ * EIP-207 Global Control API:
+ * Record Cache, FLUE, optional FLUEC, ICE and optional OCE initialization
+ * as well as ICE and optional OCE firmware download.
+ *
+ * This API is not re-entrant.
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_GLOBAL_INIT_H_
+#define EIP207_GLOBAL_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_GLOBAL_IOAREA_REQUIRED_SIZE       (2 * sizeof(void*))
+
+// place holder for device specific internal data
+typedef struct
+{
+    uint32_t placeholder[EIP207_GLOBAL_IOAREA_REQUIRED_SIZE];
+} EIP207_Global_IOArea_t;
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Error_t
+ *
+ * Status (error) code type returned by these API functions
+ * See each function "Return value" for details.
+ *
+ * EIP207_GLOBAL_NO_ERROR : successful completion of the call.
+ * EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ * EIP207_GLOBAL_ARGUMENT_ERROR :  invalid argument for a function parameter.
+ * EIP207_GLOBAL_ILLEGAL_IN_STATE : illegal state transition
+ * EIP207_GLOBAL_INTERNAL_ERROR : failure due to internal error
+ */
+typedef enum
+{
+    EIP207_GLOBAL_NO_ERROR = 0,
+    EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR,
+    EIP207_GLOBAL_ARGUMENT_ERROR,
+    EIP207_GLOBAL_ILLEGAL_IN_STATE,
+    EIP207_GLOBAL_INTERNAL_ERROR
+} EIP207_Global_Error_t;
+
+// 64-bit data structure
+typedef struct
+{
+    uint32_t Value64_Lo; // Lowest 32 bits of the 64-bit value
+    uint32_t Value64_Hi; // Highest 32 bits of the 64-bit value
+} EIP207_Global_Value64_t;
+
+typedef struct
+{
+    // Version information
+    unsigned int Major;
+    unsigned int Minor;
+    unsigned int PatchLevel;
+
+    // Pointer to the memory location where the firmware image resides
+    const uint32_t * Image_p;
+
+    // Firmware image size in 32-bit words
+    unsigned int ImageWordCount;
+
+} EIP207_Firmware_t;
+
+// EIP-207 HW version
+typedef struct
+{
+    // The basic EIP number.
+    uint8_t EipNumber;
+
+    // The complement of the basic EIP number.
+    uint8_t ComplmtEipNumber;
+
+    // Hardware Patch Level.
+    uint8_t HWPatchLevel;
+
+    // Minor Hardware revision.
+    uint8_t MinHWRevision;
+
+    // Major Hardware revision.
+    uint8_t MajHWRevision;
+} EIP207_Version_t;
+
+// EIP-207 HW options
+typedef struct
+{
+    // Number of cache sets implemented, in range 1...3
+    uint8_t NofCacheSets;
+
+    // Number of external (non-Host) clients on the Flow Record Cache
+    // (for each of the cache sets if more than one of those are present)
+    uint8_t NofFRC_Clients;
+
+    // Number of external (non-Host) clients on the Transform Record Cache
+    // (for each of the cache sets if more than one of those are present)
+    uint8_t NofTRC_Clients;
+
+    // True when Transform Record Cache logic is combined with the Flow Record
+    // Cache logic (i.e. they share the processing pipeline, administration
+    // control logic and RAM, but have separate client states and Host client
+    // access interfaces).
+    bool fCombinedFRC_TRC;
+
+    // Number of external (non-Host) clients on the ARC4 State Record Cache
+    // (for each of the cache sets if more than one of those are present)
+    // Set to 0 when the ARC4 State Record Cache is not present
+    uint8_t NofARC4_Clients;
+
+    // True when the ARC4 Record Cache is present
+    bool fARC4Present;
+
+    // True when ARC4 State Record Cache logic is combined with the Flow Record
+    // Cache logic (i.e. they share the processing pipeline, administration
+    // control logic and RAM, but have separate client states and Host client
+    // access interfaces).
+    // Only valid when NofARC4_Clients is not 0.
+    bool fCombinedFRC_ARC4;
+
+    // True when ARC4 State Record Cache logic is combined with the Transform
+    // Record Cache logic (i.e. they share the processing pipeline,
+    // administration control logic and RAM, but have separate client states
+    // and Host client access interfaces).
+    // Only valid when NofARC4_Clients is not 0.
+    bool fCombinedTRC_ARC4;
+
+    // Number of clients to the flow hash and lookup logic, independent from
+    // the number of cache sets.
+    uint8_t NofLookupClients;
+
+    // True when the Flow lookup logic is fitted with a cache RAM.
+    bool fLookupCached;
+
+    // Number of lookup tables supported by the flow lookup logic
+    uint8_t NofLookupTables;
+
+} EIP207_Options_t;
+
+// Capabilities structure for EIP-207 HW
+typedef struct
+{
+    // EIP-207 HW shell
+    EIP207_Options_t     EIP207_Options;
+    EIP207_Version_t     EIP207_Version;
+
+} EIP207_Global_Capabilities_t;
+
+// Classification Engine clocks per one tick for
+// the blocking next command logic
+typedef enum
+{
+    EIP207_BLOCK_CLOCKS_16 = 0,
+    EIP207_BLOCK_CLOCKS_32,
+    EIP207_BLOCK_CLOCKS_64,
+    EIP207_BLOCK_CLOCKS_128,
+    EIP207_BLOCK_CLOCKS_256,
+    EIP207_BLOCK_CLOCKS_512,
+    EIP207_BLOCK_CLOCKS_1024,
+    EIP207_BLOCK_CLOCKS_2048,
+} EIP207_BlockClocks_t;
+
+// EIP-207s FRC/TRC/ARC4RC configuration
+typedef struct
+{
+    // True when the record cache must be enabled
+    bool fEnable;
+
+    // True when the block next command logic is disabled
+    bool fNonBlock;
+
+    // A blocked command will be released automatically after 3 ticks of
+    // a free-running timer whose speed is set by this field.
+    // This parameter configures the number of the Classification Engine
+    // clocks per one tick, see EIP207_BlockClocks_t values
+    uint8_t BlockClockCount;
+
+    // Record base address
+    EIP207_Global_Value64_t RecBaseAddr;
+
+    // Number of words in Admin RAM.
+    unsigned int AdminWordCount;
+
+    // Number of words in Data RAM.
+    unsigned int DataWordCount;
+
+} EIP207_Global_CacheParams_t;
+
+// EIP-207s FRC/TRC/ARC4RC status information
+typedef struct
+{
+    // True when a Host bus master read access from this cache
+    // resulted in an error.
+    bool fDMAReadError;
+
+    // True when a Host bus master write access from this cache
+    // resulted in an error.
+    bool fDMAWriteError;
+
+    // True when a non-correctable ECC error is detected in the Record Cache
+    // Administration RAM. In case of this error the Record Cache will enter the
+    // software reset state.
+    bool fAdminEccErr;
+
+    // True when a non-correctable ECC error is detected in the Record Cache
+    // Data RAM. In case of this error the Record Cache will remain
+    // operational, only the packets for the corrupted record will be flushed.
+    bool fDataEccErr;
+
+    // True when a non-correctable ECC error is detected in the Record Cache
+    // Data RAM. In case of this error the Record Cache will enter the
+    // software reset state.
+    bool fDataEccOflo;
+
+} EIP207_Global_CacheStatus_t;
+
+// EIP207 Cache statistics.
+typedef struct
+{
+    // Number of prefetches executed
+    uint64_t PrefetchExec;
+    // Number of prefetches blocked
+    uint64_t PrefetchBlock;
+    // Number of pretetches with DMA
+    uint64_t PrefetchDMA;
+    // Number of select operations
+    uint64_t SelectOps;
+    // Number of select operations with DMA
+    uint64_t SelectDMA;
+    // Number of internal DMA writes
+    uint64_t IntDMAWrite;
+    // Number of external DMA writes
+    uint64_t ExtDMAWrite;
+    // Number of invalidate operations
+    uint64_t InvalidateOps;
+    // Read DMA error flags
+    uint32_t ReadDMAErrFlags;
+    // Number of read DMA errors
+    uint32_t ReadDMAErrors;
+    // Number of write DMA errors
+    uint32_t WriteDMAErrors;
+    // Number of invalidates caused by ECC errors
+    uint32_t InvalidateECC;
+    // Number of correctable ECC errors in Data RAM
+    uint32_t DataECCCorr;
+    // Number of correctable ECC errors in Admin RAM
+    uint32_t AdminECCCorr;
+} EIP207_Global_CacheDebugStatistics_t;
+
+typedef struct
+{
+    EIP207_Global_CacheParams_t FRC [EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+    EIP207_Global_CacheParams_t TRC [EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+    EIP207_Global_CacheParams_t ARC4[EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+} EIP207_Global_CacheConfig_t;
+
+// Flow Hash IV
+// Although there are as many flow hash engines in the Classification Support
+// module (EIP-207s) as there are Pull-up Micro-engines in the Classification
+// Engines (EIP-207c), they all use the same IV value to start their
+// calculations from.
+typedef struct
+{
+    uint32_t IV_Word32[4]; // must be written with a true random value
+} EIP207_Hash_IV_t;
+
+// Flow hash table configuration parameters,
+// there can be multiple (f) flow hash tables
+typedef struct
+{
+    // True when transform record pre-fetch triggering must be done in the Flow
+    // Record Cache for flow lookups done via this hash table.
+    bool fPrefetchXform;
+
+    // True when ARC4 state record pre-fetch triggering must be done
+    // in the Flow Record Cache for flow lookups done via this hash table.
+    bool fPrefetchARC4State;
+
+    // True when caching of the flow lookups is enabled for this hash table.
+    bool fLookupCached;
+
+} EIP207_Global_FlowHashTable_t;
+
+// Flow Look-Up Engine (FLUE) configuration
+typedef struct
+{
+    // Flow hash calculation IV data
+    EIP207_Hash_IV_t IV;
+
+    // When true the lookup in Host memory is only started on a failed flow
+    // lookup cache access. When false the read from the hash table in Host
+    // memory is started in parallel with the flow lookup cache access.
+    bool fDelayMemXS;
+
+    // Number of intermediate entries cached when performing a flow lookup
+    uint8_t CacheChain;
+
+    // Number of configured tables in the HashTable parameter,
+    // may not exceed EIP207_MAX_NOF_FLUE_HASH_TABLES
+    unsigned int HashTablesCount;
+
+    EIP207_Global_FlowHashTable_t
+                HashTable[EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE];
+
+    // Number of packet interfaces in the InterfaceIndex parameter.
+    // may not exceed EIP207_FLUE_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+    unsigned int InterfacesCount;
+
+    unsigned int InterfaceIndex[EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE];
+
+} EIP207_Global_FLUEConfig_t;
+
+// This data structure represents EIP-207s Input Classification Engine (ICE)
+// global statistics.
+typedef struct
+{
+    EIP207_Global_Value64_t DroppedPacketsCounter;
+
+    uint32_t                OutboundPacketCounter;
+
+    EIP207_Global_Value64_t OutboundOctetsCounter;
+
+    uint32_t                InboundPacketsCounter;
+
+    EIP207_Global_Value64_t InboundOctetsCounter;
+
+} EIP207_Global_ICE_GlobalStats_t;
+
+// This data structure represents EIP-207s Output Classification Engine (OCE)
+// global statistics.
+typedef struct
+{
+    // For future extensions:
+    //   to be filled in with the actual OCE global statistics
+    EIP207_Global_Value64_t DroppedPacketsCounter;
+
+} EIP207_Global_OCE_GlobalStats_t;
+
+// This data structure represents global statistics.
+typedef struct
+{
+    // EIP-207c ICE Global Statistics
+    EIP207_Global_ICE_GlobalStats_t ICE;
+
+    // EIP-207c OCE Global Statistics
+    // Note: Not used in some EIP-207 HW versions and
+    //       for these versions these counters will not be updated.
+    EIP207_Global_OCE_GlobalStats_t OCE;
+
+} EIP207_Global_GlobalStats_t;
+
+// This data structure represents the clock count data as generated by
+// the Classification Engine timer which speed is configured by
+// the TimerPrescaler parameter in the EIP207_Global_Firmware_Load() function.
+// The clock count is updated when a packet is processed and represents
+// the timestamp of the last packet.
+typedef struct
+{
+    // EIP-207c ICE clock count
+    EIP207_Global_Value64_t ICE;
+
+    // EIP-207c OCE clock count
+    // Note: Not used in some EIP-207c HW versions and
+    //       for these versions the OCE timestamp will not be updated.
+    EIP207_Global_Value64_t OCE;
+
+} EIP207_Global_Clock_t;
+
+// EIP-207c Classification Engine (CE) status information
+typedef struct
+{
+    // True when a correctable ECC error has been detected
+    // by the Pull-Up micro-engine
+    bool fPUE_EccCorr;
+
+    // True when a non-correctable ECC error has been detected
+    // by the Pull-Up micro-engine
+    bool fPUE_EccDerr;
+
+    // True when a correctable ECC error has been detected
+    // by the PostProcessor micro-engine
+    bool fFPP_EccCorr;
+
+    // True when a non-correctable ECC error has been detected
+    // by the PostProcessor micro-engine
+    bool fFPP_EccDerr;
+
+    // The Classification Engine timer overflow
+    bool fTimerOverflow;
+
+} EIP207_Global_CE_Status_t;
+
+// Flow Look-Up Engine (FLUE) status information
+typedef struct
+{
+    // Error bit mask 1, bits definition is implementation-specific
+    uint32_t Error1;
+
+    // Error bit mask 2, bits definition is implementation-specific
+    uint32_t Error2;
+
+} EIP207_Global_FLUE_Status_t;
+
+// Classification Engine status information
+typedef struct
+{
+    // The EIP-207c Input Classification Engine (ICE)
+    EIP207_Global_CE_Status_t ICE;
+
+    // The EIP-207c Output Classification Engine (OCE)
+    // Note: OCE is not used in some EIP-207 HW versions and
+    //        these flags are set to false in this case.
+    EIP207_Global_CE_Status_t OCE;
+
+    // Debug statistics counters.
+    EIP207_Global_CacheDebugStatistics_t FRCStats[EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+    EIP207_Global_CacheDebugStatistics_t TRCStats[EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+
+    // Fatal DMA errors reported by the Record Caches (FRC/TRC/ARC4RC)
+    // The engine must be recovered by means of the Global SW Reset or
+    // the HW Reset
+    EIP207_Global_CacheStatus_t FRC [EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+    EIP207_Global_CacheStatus_t TRC [EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+    EIP207_Global_CacheStatus_t ARC4RC [EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE];
+
+    // Errors reported by the EIP-207s Flow Look-Up Engine (FLUE).
+    EIP207_Global_FLUE_Status_t FLUE;
+
+} EIP207_Global_Status_t;
+
+// Firmware configuration data structure.
+typedef struct {
+    bool fTokenExtensionsEnable; /* Use extensions to command/result tokens */
+    bool fIncrementPktID; /* increment packet ID in tunnel headers */
+    uint8_t DTLSRecordHeaderAlign; /* Size of DTLS record headers in decrypted
+                                      output */
+    uint8_t ECNControl; /* Bit mask controlling ECN packet drops */
+    uint16_t PktID; /* Initial value of packet ID */
+
+    bool fDTLSDeferCCS; /* Defer DTLS packets of type CCS to slow path */
+    bool fDTLSDeferAlert; /* Defer DTLS packets of type Alert to slow path */
+    bool fDTLSDeferHandshake; /* Defer DTLS packets of type Handshake to slow path */
+    bool fDTLSDeferAppData; /* Defer DTLS packets of type AppData to slow path */
+    bool fDTLSDeferCAPWAP; /* Defer DTLS packets with CAPWAP to slow path */
+
+    bool fRedirRingEnable; /* Enable the redirection ring */
+    bool fAlwaysRedirect; /* Always redirect inline to redirection ring */
+    uint8_t RedirRing;     /* Ring ID of redirection ring */
+    uint16_t TransformRedirEnable; /* Enable per-interface the per-transform redirect. */
+} EIP207_Firmware_Config_t;
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Init
+ *
+ * This function performs the initialization of the EIP-207 Global Control HW
+ * interface and transits the API to the "Caches Enabled" state.
+ *
+ * This function returns the EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Global Control Driver Library configuration
+ * and the use EIP-207 HW revision or configuration.
+ *
+ * Note: This function should be called either after the HW Reset or
+ *       after the Global SW Reset.
+ *       It must be called before any other functions of this API are called
+ *       for this Classification Engine instance.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area data for
+ *     the Classification Engine instance identified by the Device parameter.
+ *
+ * Device (input)
+ *     Handle for the EIP-207 Global Control device instance returned
+ *     by Device_Find(). There can be only one device instance for the
+ *     EIP-207 Global HW interface.
+ *
+ * CacheConf_p (input, output)
+ *     EIP-207s FRC/TRC/ARC4RC configuration parameters
+ *
+ * FLUEConf_p (input)
+ *     EIP-207s Flow Hash & Look-Up Engine configuration parameters
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ */
+EIP207_Global_Error_t
+EIP207_Global_Init(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device,
+        EIP207_Global_CacheConfig_t * const CacheConf_p,
+        const EIP207_Global_FLUEConfig_t * const FLUEConf_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Firmware_Load
+ *
+ * This function performs the initialization of the EIP-207 Classification
+ * Engine internal RAM, performs the firmware download and transits the API to
+ * the "Firmware Loaded" state. The function also clears the global statistics.
+ *
+ * Note: This function should be called after EIP207_Global_Init()
+ *
+ * IOArea_p (output)
+ *     Pointer to the IO Area for the Classification Engine.
+ *
+ * TimerPrescaler (input)
+ *     Prescaler setting to let the 64 bit timer increment at a fixed rate
+ *
+ * IPUE_Firmware_p (input, output)
+ *     Pointer to the firmware data structure for the Input Pull-up
+ *     micro-engine.
+ *     The adapter has to pass a valid image pointer and size.
+ *     The adapter can optionally set the Major, Minor and PatchLevel fields
+ *     to 0, in which case this function returns the acutal version fields
+ *     of the firmware loaded. If the adapter sets one of them to a nonzero
+ *     value, they have to match with the actual values of the loaded firmware.
+ *
+ * IFPP_Firmware_p (input, output)
+ *     Pointer to the firmware data structure for the Input Flow
+ *     The adapter has to pass a valid image pointer and size.
+ *     The adapter can optionally set the Major, Minor and PatchLevel fields
+ *     to 0, in which case this function returns the acutal version fields
+ *     of the firmware loaded. If the adapter sets one of them to a nonzero
+ *     value, they have to match with the actual values of the loaded firmware.
+ *     Post-processor micro-engine.
+ *
+ * OPUE_Firmware_p (input, output)
+ *     Pointer to the firmware data structure for the Output Pull-up
+ *     micro-engine.
+ *     The adapter has to pass a valid image pointer and size.
+ *     The adapter can optionally set the Major, Minor and PatchLevel fields
+ *     to 0, in which case this function returns the acutal version fields
+ *     of the firmware loaded. If the adapter sets one of them to a nonzero
+ *     value, they have to match with the actual values of the loaded firmware.
+ *     Note: Not used in some EIP-207 HW versions.
+ *
+ * OFPP_Firmware_p (input, output)
+ *     Pointer to the firmware data structure for the Output Flow
+ *     Post-processor micro-engine.
+ *     The adapter has to pass a valid image pointer and size.
+ *     The adapter can optionally set the Major, Minor and PatchLevel fields
+ *     to 0, in which case this function returns the acutal version fields
+ *     of the firmware loaded. If the adapter sets one of them to a nonzero
+ *     value, they have to match with the actual values of the loaded firmware.
+ *     Note: Not used in some EIP-207 HW versions.
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ *     EIP207_GLOBAL_INTERNAL_ERROR : firmware download failed
+ */
+EIP207_Global_Error_t
+EIP207_Global_Firmware_Load(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const IPUE_Firmware_p,
+        EIP207_Firmware_t * const IFPP_Firmware_p,
+        EIP207_Firmware_t * const OPUE_Firmware_p,
+        EIP207_Firmware_t * const OFPP_Firmware_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_HWRevision_Get
+ *
+ * This function returns EIP-207 hardware revision
+ * information in the Capabilities_p data structure.
+ *
+ * IOArea_p (output)
+ *     Pointer to the IO Area for the Classification Engine.
+ *
+ * Capabilities_p (output)
+ *     Pointer to the place holder in memory where the device capability
+ *     information will be stored.
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ */
+EIP207_Global_Error_t
+EIP207_Global_HWRevision_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        EIP207_Global_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_GlobalStats_Get
+ *
+ * This function obtains global statistics for the Classification Engine.
+ *
+ * IOArea_p (output)
+ *     Pointer to the IO Area for the Classification Engine.
+ *
+ * CE_Number (input)
+ *     Number of the CE for which the status must be obtained.
+ *
+ * GlobalStats_p (output)
+ *     Pointer to the data structure where the global statistics will be stored.
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ *     EIP207_GLOBAL_INTERNAL_ERROR : failed to read 64-bit counter value
+ */
+EIP207_Global_Error_t
+EIP207_Global_GlobalStats_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_GlobalStats_t * const GlobalStats_p);
+
+
+/*--------------------- -------------------------------------------------------
+ * EIP207_Global_ClockCount_Get
+ *
+ * Retrieve the current clock count as used by the Classification Engine.
+ *
+ * IOArea_p (output)
+ *     Pointer to the IO Area for the Classification Engine.
+ *
+ * CE_Number (input)
+ *     Number of the CE for which the status must be obtained.
+ *
+ * Clock_p (output)
+ *     Current clock count used by the engine (least significant word).
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ *     EIP207_GLOBAL_INTERNAL_ERROR : failed to read 64-bit counter value
+ */
+EIP207_Global_Error_t
+EIP207_Global_ClockCount_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_Clock_t * const Clock_p);
+
+
+/*--------------------- -------------------------------------------------------
+ * EIP207_Global_Status_Get
+ *
+ * Retrieve the Classification Engine status information.
+ *
+ * IOArea_p (output)
+ *     Pointer to the IO Area for the Classification Engine.
+ *
+ * CE_Number (input)
+ *     Number of the CE for which the status must be obtained.
+ *
+ * Status_p (output)
+ *     Pointer to the data structure where the Classification Engine
+ *     status information will be stored.
+ *
+ * fFatalError_p (output)
+ *     Pointer to memory where the boolean flag will be stored. The flag
+ *     is set to true when this function reports one or several fatal errors.
+ *     A fatal error requires the engine Global SW or HW Reset.
+ *
+ * Return value
+ *     EIP207_GLOBAL_NO_ERROR
+ *     EIP207_GLOBAL_ARGUMENT_ERROR
+ *     EIP207_GLOBAL_ILLEGAL_IN_STATE
+ */
+EIP207_Global_Error_t
+EIP207_Global_Status_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_Status_t * const Status_p,
+        bool * const fFatalError_p);
+
+
+#endif /* EIP207_GLOBAL_INIT_H_ */
+
+
+/* end of file eip207_global_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface.h
new file mode 100644
index 0000000..38b1102
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface.h
@@ -0,0 +1,201 @@
+/* eip207_hw_interface.h
+ *
+ * EIP-207 HW interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_HW_INTERFACE_H_
+#define EIP207_HW_INTERFACE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint16_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-207 HIA registers
+ *****************************************************************************/
+// EIP-207c ICE EIP number (0xCF) and complement (0x30)
+#define EIP207_ICE_SIGNATURE            ((uint16_t)0x30CF)
+
+#define EIP207_REG_OFFS                 4
+#define EIP207_REG_MAP_SIZE             8192
+
+// EIP-207c Classification Engine n (n - number of the CE)
+// Input Side
+
+#define EIP207_ICE_REG_SCRATCH_RAM(n)  ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_SCRATCH_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_ADAPT_CTRL(n)   ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_ADAPT_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_PUE_CTRL(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUE_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_PUE_DEBUG(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUE_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_PUTF_CTRL(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUTF_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_SCRATCH_CTRL(n) ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUTF_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_TIMER_LO(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUTF_CTRL_BASE) + \
+                                         (0x02 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_TIMER_HI(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUTF_CTRL_BASE) + \
+                                         (0x03 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_UENG_STAT(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PUTF_CTRL_BASE) + \
+                                         (0x04 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_FPP_CTRL(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_FPP_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_FPP_DEBUG(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_FPP_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_PPTF_CTRL(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_ICE_REG_PPTF_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_ICE_REG_RAM_CTRL(n)      ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_ICE_REG_RAM_CTRL_BASE) + \
+                                          (0x00 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_RAM_CTRL_RSV1(n) ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_ICE_REG_RAM_CTRL_BASE) + \
+                                          (0x01 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_OPTIONS(n)       ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_ICE_REG_RAM_CTRL_BASE) + \
+                                          (0x02 * EIP207_REG_OFFS)))
+#define EIP207_ICE_REG_VERSION(n)       ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_ICE_REG_RAM_CTRL_BASE) + \
+                                          (0x03 * EIP207_REG_OFFS)))
+
+// Access space for Classification RAM (size 64 KB)
+#define EIP207_CS_RAM_XS_SPACE_WORD_COUNT  16384
+
+// EIP-207s Classification Support module (p - number of the cache set)
+
+// General Record Cache (FRC/TRC/ARC4RC) register interface
+#define EIP207_RC_REG_DATA_BYTE_OFFSET    0x400
+#define EIP207_FRC_REG_DATA_BYTE_OFFSET   EIP207_RC_REG_DATA_BYTE_OFFSET
+#define EIP207_TRC_REG_DATA_BYTE_OFFSET   EIP207_RC_REG_DATA_BYTE_OFFSET
+
+#define EIP207_RC_HDR_WORD_3_RELOAD_BIT   BIT_15
+
+#define EIP207_RC_REG_CTRL(base,p)      ((EIP207_REG_MAP_SIZE * p) + \
+                                         (base + \
+                                          (0x00 * EIP207_REG_OFFS)))
+#define EIP207_RC_REG_LASTRES(base,p)   ((EIP207_REG_MAP_SIZE * p) + \
+                                         (base + \
+                                          (0x01 * EIP207_REG_OFFS)))
+
+#define EIP207_RC_REG_PARAMS_BASE       0x00020
+
+// RC RAM (top 1036 bytes are accessible)
+#define EIP207_RC_REG_DATA_WORD_COUNT   259
+
+#define EIP207_RC_REG_DATA_BASE       0x00000
+#define EIP207_RC_REG_DATA(base,p)    ((EIP207_REG_MAP_SIZE * p) + \
+                                       ((base + EIP207_RC_REG_DATA_BASE) + \
+                                        (0x00 * EIP207_REG_OFFS)))
+
+// EIP-207s Classification Support, Flow Hash Engine (FHASH)
+#define EIP207_FHASH_REG_IV_0           ((EIP207_FHASH_REG_BASE) + \
+                                          (0x00 * EIP207_REG_OFFS))
+#define EIP207_FHASH_REG_IV_1           ((EIP207_FHASH_REG_BASE) + \
+                                          (0x01 * EIP207_REG_OFFS))
+#define EIP207_FHASH_REG_IV_2           ((EIP207_FHASH_REG_BASE) + \
+                                          (0x02 * EIP207_REG_OFFS))
+#define EIP207_FHASH_REG_IV_3           ((EIP207_FHASH_REG_BASE) + \
+                                          (0x03 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support, DMA Control
+#define EIP207_CS_DMA_REG_RAM_CTRL      ((EIP207_CS_DMA_REG_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS))
+#define EIP207_CS_DMA_REG_RAM_CTRL2     ((EIP207_CS_DMA_REG_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support, Options and Versions
+#define EIP207_CS_REG_RAM_CTRL          ((EIP207_CS_REG_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS))
+#define EIP207_CS_REG_RESERVED_1        ((EIP207_CS_REG_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS))
+#define EIP207_CS_REG_OPTIONS           ((EIP207_CS_REG_BASE) + \
+                                         (0x02 * EIP207_REG_OFFS))
+#define EIP207_CS_REG_VERSION           ((EIP207_CS_REG_BASE) + \
+                                         (0x03 * EIP207_REG_OFFS))
+
+// EIP-207s Classification Support EIP number (0xCF) and complement (0x30)
+#define EIP207_CS_SIGNATURE             EIP207_ICE_SIGNATURE
+
+// Register default value
+#define EIP207_CS_REG_RAM_CTRL_DEFAULT      0x00000000
+
+#define EIP207_ICE_REG_RAM_CTRL_DEFAULT     0x00000000
+#define EIP207_ICE_REG_PUE_CTRL_DEFAULT     0x00000001
+#define EIP207_ICE_REG_FPP_CTRL_DEFAULT     0x00000001
+#define EIP207_ICE_REG_SCRATCH_CTRL_DEFAULT 0x001F0200
+
+#define EIP207_RC_REG_CTRL_DEFAULT          0x00000007
+#define EIP207_RC_REG_FREECHAIN_DEFAULT     0x00000000
+
+#define EIP207_FLUE_REG_OFFSETS_DEFAULT     0x00000000
+#define EIP207_FLUE_REG_ARC4_OFFSET_DEFAULT 0x00000000
+
+
+// EIP-207 HW interface extensions
+#include "eip207_hw_interface_ext.h"
+
+// EIP-207 Record Cache HW interface extensions
+#include "eip207_rc_hw_interface_ext.h"
+
+
+#endif /* EIP207_HW_INTERFACE_H_ */
+
+
+/* end of file eip207_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface_ext.h
new file mode 100644
index 0000000..a081194
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_hw_interface_ext.h
@@ -0,0 +1,147 @@
+/* eip207_hw_interface_ext.h
+ *
+ * EIP-207 HW interface extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_HW_INTERFACE_EXT_H_
+#define EIP207_HW_INTERFACE_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// VM-specific register sets in 32-byte blocks
+#define EIP207_FLUE_VM_REG_MAP_SIZE       32
+
+
+// Read/Write register constants
+
+// EIP-207s Classification Support, Flow Look-Up Engine (FLUE), VM-specific
+// (f - number of VM)
+#define EIP207_FLUE_REG_CONFIG(f)       ((EIP207_FLUE_VM_REG_MAP_SIZE * f) + \
+                                         ((EIP207_FLUE_CONFIG_REG_BASE) + \
+                                          (0x00 * EIP207_REG_OFFS)))
+
+// EIP-207s Classification Support, Flow Look-Up Engine (FLUE)
+#define EIP207_FLUE_REG_OFFSETS         (EIP207_FLUE_REG_BASE + \
+                                          (0x00 * EIP207_REG_OFFS))
+#define EIP207_FLUE_REG_ARC4_OFFSET     (EIP207_FLUE_REG_BASE + \
+                                          (0x01 * EIP207_REG_OFFS))
+
+#define EIP207_FLUE_REG_ENABLED_LO      (EIP207_FLUE_ENABLED_REG_BASE + \
+                                          (0x02 * EIP207_REG_OFFS))
+#define EIP207_FLUE_REG_ENABLED_HI      (EIP207_FLUE_ENABLED_REG_BASE + \
+                                          (0x03 * EIP207_REG_OFFS))
+#define EIP207_FLUE_REG_ERROR_LO        (EIP207_FLUE_ENABLED_REG_BASE + \
+                                          (0x04 * EIP207_REG_OFFS))
+#define EIP207_FLUE_REG_ERROR_HI        (EIP207_FLUE_ENABLED_REG_BASE + \
+                                          (0x05 * EIP207_REG_OFFS))
+
+#define EIP207_FLUE_REG_IFC_LUT(f)       (EIP207_FLUE_IFC_LUT_REG_BASE + \
+                                          ((f) * EIP207_REG_OFFS))
+
+// EIP-207c Classification Engine n (n - number of the CE)
+// Output Side
+
+#define EIP207_OCE_REG_SCRATCH_RAM(n)  ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_SCRATCH_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_ADAPT_CTRL(n)   ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_ADAPT_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_PUE_CTRL(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUE_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_PUE_DEBUG(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUE_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_PUTF_CTRL(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUTF_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_SCRATCH_CTRL(n) ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUTF_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_TIMER_LO(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUTF_CTRL_BASE) + \
+                                         (0x02 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_TIMER_HI(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUTF_CTRL_BASE) + \
+                                         (0x03 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_UENG_STAT(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PUTF_CTRL_BASE) + \
+                                         (0x04 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_FPP_CTRL(n)     ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_FPP_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_FPP_DEBUG(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_FPP_CTRL_BASE) + \
+                                         (0x01 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_PPTF_CTRL(n)    ((EIP207_REG_MAP_SIZE * n) + \
+                                        ((EIP207_OCE_REG_PPTF_CTRL_BASE) + \
+                                         (0x00 * EIP207_REG_OFFS)))
+
+#define EIP207_OCE_REG_RAM_CTRL(n)      ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_OCE_REG_RAM_CTRL_BASE) + \
+                                          (0x00 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_RAM_CTRL_RSV1(n) ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_OCE_REG_RAM_CTRL_BASE) + \
+                                          (0x01 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_OPTIONS(n)       ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_OCE_REG_RAM_CTRL_BASE) + \
+                                          (0x02 * EIP207_REG_OFFS)))
+#define EIP207_OCE_REG_VERSION(n)       ((EIP207_REG_MAP_SIZE * n) + \
+                                         ((EIP207_OCE_REG_RAM_CTRL_BASE) + \
+                                          (0x03 * EIP207_REG_OFFS)))
+
+// Output Side: reserved
+
+// Register default value
+#define EIP207_FLUE_REG_CONFIG_DEFAULT      0x00000000
+
+#define EIP207_FLUE_REG_IFC_LUT_DEFAULT     0x00000000
+
+#define EIP207_OCE_REG_RAM_CTRL_DEFAULT     0x00000000
+#define EIP207_OCE_REG_PUE_CTRL_DEFAULT     0x00000001
+#define EIP207_OCE_REG_FPP_CTRL_DEFAULT     0x00000001
+#define EIP207_OCE_REG_SCRATCH_CTRL_DEFAULT 0x001F0200
+
+
+#endif /* EIP207_HW_INTERFACE_EXT_H_ */
+
+
+/* end of file eip207_hw_interface_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_ice.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_ice.h
new file mode 100644
index 0000000..85889ce
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_ice.h
@@ -0,0 +1,102 @@
+/* eip207_ice.h
+ *
+ * EIP-207c Input Classification Engine (ICE) interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_ICE_H_
+#define EIP207_ICE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-207 Global Control Init API
+#include "eip207_global_init.h"         // EIP207_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Firmware_Load(
+        const Device_Handle_t Device,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const PUE_Firmware_p,
+        EIP207_Firmware_t * const FPP_Firmware_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_GlobalStats_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_ICE_GlobalStats_t * const ICE_GlobalStats_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_ClockCount_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_Value64_t * const ICE_Clock_p);
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_ICE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_CE_Status_t * const ICE_Status_p);
+
+
+/* end of file eip207_ice.h */
+
+
+#endif /* EIP207_ICE_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0.h
new file mode 100644
index 0000000..ff23662
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0.h
@@ -0,0 +1,433 @@
+/* eip207_level0.h
+ *
+ * EIP-207 Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_LEVEL0_H_
+#define EIP207_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+#include "device_swap.h"        // Device_SwapEndian32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 Global Register Write/Read Functions
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Read32
+ *
+ * This routine writes to a Register location in the EIP-207.
+ */
+static inline uint32_t
+EIP207_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Write32
+ *
+ * This routine writes to a Register location in the EIP-207.
+ */
+static inline void
+EIP207_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+
+#ifdef EIP207_CLUSTERED_WRITES_DISABLE
+    // Prevent clustered write operations, break them with a read operation
+    // Note: Reading the EIP207_CS_REG_VERSION register has no side effects!
+    EIP207_Read32(Device, EIP207_CS_REG_VERSION);
+#endif
+}
+
+
+static inline bool
+EIP207_ICE_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP207_ICE_SIGNATURE);
+}
+
+
+static inline bool
+EIP207_CS_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP207_CS_SIGNATURE);
+}
+
+
+static inline void
+EIP207_CS_VERSION_RD(
+        Device_Handle_t Device,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP207_Read32(Device, EIP207_CS_REG_VERSION);
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP207_CS_OPTIONS_RD(
+        Device_Handle_t Device,
+        uint8_t * const NofLookupTables,
+        bool * const fLookupCached,
+        uint8_t * const NofLookupClients,
+        bool * const fARC4TrcCombined,
+        bool * const fARC4FrcCombined,
+        bool * const fARC4Present,
+        uint8_t * const NofArc4Clients,
+        bool * const fTrcFrcCombined,
+        uint8_t * const NofTrcClients,
+        uint8_t * const NofFrcClients,
+        uint8_t * const NofCacheSets)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP207_Read32(Device, EIP207_CS_REG_OPTIONS);
+
+    *NofLookupTables  = (uint8_t)((RevRegVal >> 28) & MASK_3_BITS);
+    *fLookupCached    = ((RevRegVal & BIT_27) != 0);
+    *NofLookupClients = (uint8_t)((RevRegVal >> 22) & MASK_5_BITS);
+    *fARC4TrcCombined = ((RevRegVal & BIT_21) != 0);
+    *fARC4FrcCombined = ((RevRegVal & BIT_20) != 0);
+    *fARC4Present     = ((RevRegVal & BIT_19) != 0);
+    *NofArc4Clients   = (uint8_t)((RevRegVal >> 14) & MASK_5_BITS);
+    *fTrcFrcCombined  = ((RevRegVal & BIT_13) != 0);
+    *NofTrcClients    = (uint8_t)((RevRegVal >> 8)  & MASK_5_BITS);
+    *NofFrcClients    = (uint8_t)((RevRegVal >> 3)  & MASK_5_BITS);
+    *NofCacheSets     = (uint8_t)((RevRegVal >> 1)  & MASK_2_BITS);
+}
+
+static inline void
+EIP207_ICE_ADAPT_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int CEnr,
+        uint32_t MaxPacketSize)
+{
+    uint32_t RegVal = 0xc0de0000;
+    RegVal |= (MaxPacketSize & 0xfffc);
+    EIP207_Write32(Device, EIP207_ICE_REG_ADAPT_CTRL(CEnr), RegVal);
+}
+
+static inline void
+EIP207_ICE_VERSION_RD(
+        Device_Handle_t Device,
+        const unsigned int CEnr,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP207_Read32(Device, EIP207_ICE_REG_VERSION(CEnr));
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP207_CS_RAM_CTRL_WR(
+        const Device_Handle_t Device,
+        const bool fFrc0Enable,
+        const bool fFrc1Enable,
+        const bool fFrc2Enable,
+        const bool fTrc0Enable,
+        const bool fTrc1Enable,
+        const bool fTrc2Enable,
+        const bool fARC4rc0Enable,
+        const bool fARC4rc1Enable,
+        const bool fARC4rc2Enable,
+        const bool fFLUECEnable)
+{
+    uint32_t RegVal = EIP207_CS_REG_RAM_CTRL_DEFAULT;
+
+    if(fFrc0Enable)
+        RegVal |= BIT_0;
+
+    if(fFrc1Enable)
+        RegVal |= BIT_1;
+
+    if(fFrc2Enable)
+        RegVal |= BIT_2;
+
+    if(fTrc0Enable)
+        RegVal |= BIT_4;
+
+    if(fTrc1Enable)
+        RegVal |= BIT_5;
+
+    if(fTrc2Enable)
+        RegVal |= BIT_6;
+
+    if(fARC4rc0Enable)
+        RegVal |= BIT_8;
+
+    if(fARC4rc1Enable)
+        RegVal |= BIT_9;
+
+    if(fARC4rc2Enable)
+        RegVal |= BIT_10;
+
+    if(fFLUECEnable)
+        RegVal |= BIT_12;
+
+    EIP207_Write32(Device, EIP207_CS_REG_RAM_CTRL, RegVal);
+}
+
+
+static inline void
+EIP207_CS_RAM_CTRL_DEFAULT_WR(
+        const Device_Handle_t Device)
+{
+    EIP207_Write32(Device,
+                   EIP207_CS_REG_RAM_CTRL,
+                   EIP207_CS_REG_RAM_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP207_RC_CTRL_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint8_t Command)
+{
+    uint32_t RegVal = EIP207_RC_REG_CTRL_DEFAULT;
+
+    RegVal &= (~MASK_4_BITS);
+    RegVal |= (uint32_t)((((uint32_t)Command)   & MASK_4_BITS));
+
+    EIP207_Write32(Device, EIP207_RC_REG_CTRL(CacheBase, CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_DATA_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const unsigned int ByteOffset,
+        const uint32_t Value32)
+{
+    EIP207_Write32(Device,
+                   EIP207_RC_REG_DATA(CacheBase + ByteOffset, CacheNr),
+                   Value32);
+}
+
+
+static inline void
+EIP207_ICE_PUTF_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint8_t TokenLimit,
+        const bool fFIFOReset)
+{
+    uint32_t RegVal = 0;
+    RegVal |= TokenLimit & MASK_8_BITS;
+
+    if (fFIFOReset)
+        RegVal |= BIT_15;
+
+    EIP207_Write32(Device, EIP207_ICE_REG_PUTF_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_PPTF_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint8_t TokenLimit,
+        const bool fFIFOReset)
+{
+    uint32_t RegVal = 0;
+    RegVal |= TokenLimit & MASK_8_BITS;
+
+    if (fFIFOReset)
+        RegVal |= BIT_15;
+
+    EIP207_Write32(Device, EIP207_ICE_REG_PPTF_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_SCRATCH_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const bool fChangeTimer,
+        const bool fTimerEnable,
+        const uint16_t TimerPrescaler,
+        const uint8_t TimerOfloBit,
+        const bool fChangeAccess,
+        const uint8_t ScratchAccess)
+{
+    uint32_t RegVal = EIP207_ICE_REG_SCRATCH_CTRL_DEFAULT;
+
+    if(fChangeTimer)
+        RegVal |= BIT_2;
+
+    if(fTimerEnable)
+        RegVal |= BIT_3;
+
+    if(fChangeAccess)
+        RegVal |= BIT_24;
+
+    RegVal |= (uint32_t)((((uint32_t)ScratchAccess)  & MASK_4_BITS)  << 25);
+
+    RegVal &= (~((uint32_t)(MASK_5_BITS << 16)));
+    RegVal |= (uint32_t)((((uint32_t)TimerOfloBit)   & MASK_5_BITS)  << 16);
+
+    RegVal &= (~((uint32_t)(MASK_12_BITS << 4)));
+    RegVal |= (uint32_t)((((uint32_t)TimerPrescaler) & MASK_12_BITS) << 4);
+
+    EIP207_Write32(Device, EIP207_ICE_REG_SCRATCH_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_SCRATCH_CTRL_IRQ_CLEAR(
+        const Device_Handle_t Device,
+        const unsigned int CENr)
+{
+    uint32_t RegVal = EIP207_Read32(Device, EIP207_ICE_REG_SCRATCH_CTRL(CENr));
+
+    // Clear Time Overflow IRQ
+    RegVal |= BIT_0;
+
+    EIP207_Write32(Device, EIP207_ICE_REG_SCRATCH_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_SCRATCH_CTRL_RD(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fTimerOfloIrq)
+{
+    uint32_t RegVal = EIP207_Read32(Device, EIP207_ICE_REG_SCRATCH_CTRL(CENr));
+
+    *fTimerOfloIrq = ((RegVal & BIT_0) != 0);
+}
+
+
+static inline void
+EIP207_ICE_RAM_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const bool fPueProgEnable,
+        const bool fFppProgEnable)
+{
+    uint32_t RegVal = EIP207_ICE_REG_RAM_CTRL_DEFAULT;
+
+    if(fPueProgEnable)
+        RegVal |= BIT_0;
+
+    if(fFppProgEnable)
+        RegVal |= BIT_1;
+
+    EIP207_Write32(Device, EIP207_ICE_REG_RAM_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_FHASH_IV_WR(
+        const Device_Handle_t Device,
+        const uint32_t IV_0,
+        const uint32_t IV_1,
+        const uint32_t IV_2,
+        const uint32_t IV_3)
+{
+    EIP207_Write32(Device, EIP207_FHASH_REG_IV_0, IV_0);
+    EIP207_Write32(Device, EIP207_FHASH_REG_IV_1, IV_1);
+    EIP207_Write32(Device, EIP207_FHASH_REG_IV_2, IV_2);
+    EIP207_Write32(Device, EIP207_FHASH_REG_IV_3, IV_3);
+}
+
+
+// EIP-207 Level0 interface extensions
+#include "eip207_level0_ext.h"
+
+// EIP-207 Record Cache Level0 interface extensions
+#include "eip207_rc_level0_ext.h"
+
+
+#endif /* EIP207_LEVEL0_H_ */
+
+
+/* end of file eip207_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0_ext.h
new file mode 100644
index 0000000..abde841
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_level0_ext.h
@@ -0,0 +1,443 @@
+/* eip207_level0_ext.h
+ *
+ * EIP-207 Level0 Internal interface extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_LEVEL0_EXT_H_
+#define EIP207_LEVEL0_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // BIT definitions, bool, uint32_t
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"    // EIP207_FLUE_REG_*
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 Global Register Write/Read Functions
+ *
+ */
+
+static inline void
+EIP207_FLUE_CONFIG_WR(
+        const Device_Handle_t Device,
+        const unsigned int HashTableId,
+        const uint8_t Function,
+        const uint8_t Generation,
+        const bool fTableEnable,
+        const bool fXSEnable)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_CONFIG_DEFAULT;
+
+    if (fTableEnable)
+        RegVal |= BIT_30;
+
+    if (fXSEnable)
+        RegVal |= BIT_31;
+
+    RegVal |= (uint32_t)((((uint32_t)Generation) & MASK_3_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)Function)   & MASK_8_BITS) << 16);
+
+    EIP207_Write32(Device, EIP207_FLUE_REG_CONFIG(HashTableId), RegVal);
+}
+
+
+static inline void
+EIP207_FLUE_OFFSET_WR(
+        const Device_Handle_t Device,
+        const bool fPrefetchXform,
+        const bool fLookupCached,
+        const uint8_t XformRecordWordOffset)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_OFFSETS_DEFAULT;
+
+    if (fPrefetchXform)
+        RegVal |= BIT_2;
+
+    if (fLookupCached)
+        RegVal |= BIT_3;
+
+    RegVal |=
+          (uint32_t)((((uint32_t)XformRecordWordOffset) & MASK_8_BITS) << 24);
+
+    EIP207_Write32(Device, EIP207_FLUE_REG_OFFSETS, RegVal);
+}
+
+
+static inline void
+EIP207_FLUE_ARC4_OFFSET_WR(
+        const Device_Handle_t Device,
+        const bool fPrefetchARC4,
+        const bool f3EntryLookup,
+        const uint8_t ARC4RecordWordOffset)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_ARC4_OFFSET_DEFAULT;
+
+    if (fPrefetchARC4)
+        RegVal |= BIT_2;
+
+    if (f3EntryLookup)
+        RegVal |= BIT_3;
+
+    RegVal |=
+          (uint32_t)((((uint32_t)ARC4RecordWordOffset) & MASK_8_BITS) << 24);
+
+    EIP207_Write32(Device, EIP207_FLUE_REG_ARC4_OFFSET, RegVal);
+}
+
+
+static inline void
+EIP207_ICE_PUE_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint16_t CurrentPc,
+        const bool fEccCorr,
+        const bool fEccDerr,
+        const bool fDebugReset,
+        const bool fSWReset)
+{
+    uint32_t RegVal = EIP207_ICE_REG_PUE_CTRL_DEFAULT;
+
+    if (!fSWReset)
+        RegVal &= (~BIT_0);
+
+    if(fDebugReset)
+        RegVal |= BIT_3;
+
+    if(fEccDerr)
+        RegVal |= BIT_14;
+
+    if(fEccCorr)
+        RegVal |= BIT_15;
+
+    RegVal |= (uint32_t)((((uint32_t)CurrentPc) & MASK_15_BITS) << 16);
+
+    EIP207_Write32(Device, EIP207_ICE_REG_PUE_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_PUE_CTRL_RD_CLEAR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fEccCorr_p,
+        bool * const fEccDerr_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_ICE_REG_PUE_CTRL(CENr));
+
+    *fEccCorr_p = ((RegVal & BIT_15) != 0);
+    *fEccDerr_p = ((RegVal & BIT_14) != 0);
+
+    // Clear correctable ECC error is detected
+    if (*fEccCorr_p )
+    {
+        if(*fEccDerr_p)
+            RegVal &= (~BIT_14);
+
+        EIP207_Write32(Device, EIP207_ICE_REG_PUE_CTRL(CENr), RegVal);
+    }
+}
+
+
+static inline void
+EIP207_ICE_FPP_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint16_t CurrentPc,
+        const bool fEccCorr,
+        const bool fEccDerr,
+        const bool fDebugReset,
+        const bool fSWReset)
+{
+    uint32_t RegVal = EIP207_ICE_REG_FPP_CTRL_DEFAULT;
+
+    if (!fSWReset)
+        RegVal &= (~BIT_0);
+
+    if (fDebugReset)
+        RegVal |= BIT_3;
+
+    if(fEccDerr)
+        RegVal |= BIT_14;
+
+    if(fEccCorr)
+        RegVal |= BIT_15;
+
+    RegVal |= (uint32_t)((((uint32_t)CurrentPc) & MASK_15_BITS) << 16);
+
+    EIP207_Write32(Device, EIP207_ICE_REG_FPP_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_ICE_FPP_CTRL_RD_CLEAR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fEccCorr_p,
+        bool * const fEccDerr_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_ICE_REG_FPP_CTRL(CENr));
+
+    *fEccCorr_p = ((RegVal & BIT_15) != 0);
+    *fEccDerr_p = ((RegVal & BIT_14) != 0);
+
+    // Clear correctable ECC error is detected
+    if (*fEccCorr_p )
+    {
+        if(*fEccDerr_p)
+            RegVal &= (~BIT_14);
+
+        EIP207_Write32(Device, EIP207_ICE_REG_FPP_CTRL(CENr), RegVal);
+    }
+}
+
+
+static inline void
+EIP207_OCE_SCRATCH_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const bool fChangeTimer,
+        const bool fTimerEnable,
+        const uint16_t TimerPrescaler,
+        const uint8_t TimerOfloBit,
+        const bool fChangeAccess,
+        const uint8_t ScratchAccess)
+{
+    uint32_t RegVal = EIP207_OCE_REG_SCRATCH_CTRL_DEFAULT;
+
+    if(fChangeTimer)
+        RegVal |= BIT_2;
+
+    if(fTimerEnable)
+        RegVal |= BIT_3;
+
+    if(fChangeAccess)
+        RegVal |= BIT_24;
+
+    RegVal |= (uint32_t)((((uint32_t)ScratchAccess)  & MASK_4_BITS)  << 25);
+
+    RegVal &= (~((uint32_t)(MASK_5_BITS << 16)));
+    RegVal |= (uint32_t)((((uint32_t)TimerOfloBit)   & MASK_5_BITS)  << 16);
+
+    RegVal &= (~((uint32_t)(MASK_12_BITS << 4)));
+    RegVal |= (uint32_t)((((uint32_t)TimerPrescaler) & MASK_12_BITS) << 4);
+
+    EIP207_Write32(Device, EIP207_OCE_REG_SCRATCH_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_OCE_SCRATCH_CTRL_RD(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fTimerOfloIrq)
+{
+    uint32_t RegVal = EIP207_Read32(Device, EIP207_OCE_REG_SCRATCH_CTRL(CENr));
+
+    *fTimerOfloIrq = ((RegVal & BIT_0) != 0);
+}
+
+
+static inline void
+EIP207_OCE_PUE_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint16_t CurrentPc,
+        const bool fEccCorr,
+        const bool fEccDerr,
+        const bool fDebugReset,
+        const bool fSWReset)
+{
+    uint32_t RegVal = EIP207_OCE_REG_PUE_CTRL_DEFAULT;
+
+    if (!fSWReset)
+        RegVal &= (~BIT_0);
+
+    if(fDebugReset)
+        RegVal |= BIT_3;
+
+    if(fEccDerr)
+        RegVal |= BIT_14;
+
+    if(fEccCorr)
+        RegVal |= BIT_15;
+
+    RegVal |= (uint32_t)((((uint32_t)CurrentPc) & MASK_15_BITS) << 16);
+
+    EIP207_Write32(Device, EIP207_OCE_REG_PUE_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_OCE_PUE_CTRL_RD_CLEAR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fEccCorr_p,
+        bool * const fEccDerr_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_OCE_REG_PUE_CTRL(CENr));
+
+    *fEccCorr_p = ((RegVal & BIT_15) != 0);
+    *fEccDerr_p = ((RegVal & BIT_14) != 0);
+
+    // Clear correctable ECC error is detected
+    if (*fEccCorr_p )
+    {
+        if(*fEccDerr_p)
+            RegVal &= (~BIT_14);
+
+        EIP207_Write32(Device, EIP207_OCE_REG_PUE_CTRL(CENr), RegVal);
+    }
+}
+
+
+static inline void
+EIP207_OCE_FPP_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const uint16_t CurrentPc,
+        const bool fEccCorr,
+        const bool fEccDerr,
+        const bool fDebugReset,
+        const bool fSWReset)
+{
+    uint32_t RegVal = EIP207_OCE_REG_FPP_CTRL_DEFAULT;
+
+    if (!fSWReset)
+        RegVal &= (~BIT_0);
+
+    if (fDebugReset)
+        RegVal |= BIT_3;
+
+    if(fEccDerr)
+        RegVal |= BIT_14;
+
+    if(fEccCorr)
+        RegVal |= BIT_15;
+
+    RegVal |= (uint32_t)((((uint32_t)CurrentPc) & MASK_15_BITS) << 16);
+
+    EIP207_Write32(Device, EIP207_OCE_REG_FPP_CTRL(CENr), RegVal);
+}
+
+
+static inline void
+EIP207_OCE_FPP_CTRL_RD_CLEAR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        bool * const fEccCorr_p,
+        bool * const fEccDerr_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_OCE_REG_FPP_CTRL(CENr));
+
+    *fEccCorr_p = ((RegVal & BIT_15) != 0);
+    *fEccDerr_p = ((RegVal & BIT_14) != 0);
+
+    // Clear correctable ECC error is detected
+    if (*fEccCorr_p )
+    {
+        if(*fEccDerr_p)
+            RegVal &= (~BIT_14);
+
+        EIP207_Write32(Device, EIP207_OCE_REG_FPP_CTRL(CENr), RegVal);
+    }
+}
+
+
+static inline void
+EIP207_OCE_RAM_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int CENr,
+        const bool fPueProgEnable,
+        const bool fFppProgEnable)
+{
+    uint32_t RegVal = EIP207_OCE_REG_RAM_CTRL_DEFAULT;
+
+    if(fPueProgEnable)
+        RegVal |= BIT_0;
+
+    if(fFppProgEnable)
+        RegVal |= BIT_1;
+
+    EIP207_Write32(Device, EIP207_OCE_REG_RAM_CTRL(CENr), RegVal);
+}
+
+
+#ifdef EIP207_FLUE_HAVE_VIRTUALIZATION
+
+static inline void
+EIP207_FLUE_IFC_LUT_WR(
+        const Device_Handle_t Device,
+        const unsigned int RegNr,
+        const unsigned int TableId0,
+        const unsigned int TableId1,
+        const unsigned int TableId2,
+        const unsigned int TableId3)
+{
+    uint32_t RegVal = EIP207_FLUE_REG_IFC_LUT_DEFAULT;
+
+    RegVal |= (TableId0 & MASK_4_BITS);
+    RegVal |= (TableId1 & MASK_4_BITS) << 8;
+    RegVal |= (TableId2 & MASK_4_BITS) << 16;
+    RegVal |= (TableId3 & MASK_4_BITS) << 24;
+
+    EIP207_Write32(Device, EIP207_FLUE_REG_IFC_LUT(RegNr), RegVal);
+}
+
+#endif
+
+
+#endif /* EIP207_LEVEL0_EXT_H_ */
+
+
+/* end of file eip207_level0_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_oce.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_oce.h
new file mode 100644
index 0000000..36723d9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_oce.h
@@ -0,0 +1,102 @@
+/* eip207_oce.h
+ *
+ * EIP-207c Output Classification Engine (OCE) interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_OCE_H_
+#define EIP207_OCE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-207 Global Control Init API
+#include "eip207_global_init.h"         // EIP207_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Firmware_Load(
+        const Device_Handle_t Device,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const PUE_Firmware_p,
+        EIP207_Firmware_t * const FPP_Firmware_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_GlobalStats_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_OCE_GlobalStats_t * const OCE_GlobalStats_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_ClockCount_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_Value64_t * const OCE_Clock_p);
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_OCE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_CE_Status_t * const OCE_Status_p);
+
+
+/* end of file eip207_oce.h */
+
+
+#endif /* EIP207_OCE_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc.h
new file mode 100644
index 0000000..c1c2df6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc.h
@@ -0,0 +1,155 @@
+/* eip207_rc.h
+ *
+ * EIP-207 Record Cache (RC) interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_RC_H_
+#define EIP207_RC_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint8_t, uint32_t, MASK_2_BITS
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Record Cache commands
+
+// Select record but do not fetch if it is not in cache
+#define EIP207_RC_CMD_SELECT_NO_FETCH     0x2
+#define EIP207_RC_CMD_WRITE_DATA          0x7
+#define EIP207_RC_CMD_SET_BITS            0xA
+
+#define EIP207_RC_REG_DATA_BYTE_OFFSET    0x400
+#define EIP207_FRC_REG_DATA_BYTE_OFFSET   EIP207_RC_REG_DATA_BYTE_OFFSET
+#define EIP207_TRC_REG_DATA_BYTE_OFFSET   EIP207_RC_REG_DATA_BYTE_OFFSET
+
+#define EIP207_RC_HDR_WORD_3_RELOAD_BIT   BIT_15
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_BaseAddr_Set
+ *
+ * Set the memory base address for an EIP-207 Record Cache.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * CacheBase (input)
+ *      Base address of the Record Cache, must be one of the following:
+ *      EIP207_FRC_REG_BASE    - for the Flow Record Cache,
+ *      EIP207_TRC_REG_BASE    - for the Transform Record Cache,
+ *      EIP207_ARC4RC_REG_BASE - for the ARC4 Record Cache
+ *
+ * CacheNr (input)
+ *      Cache set number. There can be multiple cache sets used.
+ *
+ * Address (input)
+ *      Lower half (32 bits) of the base address.
+ *
+ * UpperAddress (input)
+ *      Upper half (32 bits) of the base address.
+ *
+ * Return code
+ *      None
+ */
+void
+EIP207_RC_BaseAddr_Set(
+            const Device_Handle_t Device,
+            const uint32_t CacheBase,
+            const unsigned int CacheNr,
+            const uint32_t Address,
+            const uint32_t UpperAddress);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Update
+ *
+ * This function updates a requested record in the EIP-207 Record Cache.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * CacheBase (input)
+ *      Base address of the Record Cache, must be one of the following:
+ *      EIP207_FRC_REG_BASE    - for the Flow Record Cache,
+ *      EIP207_TRC_REG_BASE    - for the Transform Record Cache,
+ *      EIP207_ARC4RC_REG_BASE - for the ARC4 Record Cache
+ *
+ * CacheNr (input)
+ *      Cache set number. There can be multiple cache sets used.
+ *
+ * Rec_DMA_Addr (input)
+ *      DMA address of the record to be updated in the record cache.
+ *
+ * Command (input)
+ *      Cache command that must be used for the update operation.
+ *
+ * ByteOffset (input)
+ *      Byte offset in the record where the Value32 must be written
+ *
+ * Value32 (input)
+ *      Value that must be written to the record in the cache.
+ *
+ * Return code
+ *      None
+ */
+void
+EIP207_RC_Record_Update(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint32_t Rec_DMA_Addr,
+        const uint8_t Command,
+        const unsigned int ByteOffset,
+        const uint32_t Value32);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Dummy_Addr_Get
+ *
+ * This function returns the dummy record address.
+ */
+unsigned int
+EIP207_RC_Record_Dummy_Addr_Get(void);
+
+
+/* end of file eip207_rc.h */
+
+
+#endif /* EIP207_RC_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_hw_interface_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_hw_interface_ext.h
new file mode 100644
index 0000000..cfa3f69
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_hw_interface_ext.h
@@ -0,0 +1,100 @@
+/* eip207_rc_hw_interface_ext.h
+ *
+ * EIP-207 HW interface extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_RC_HW_INTERFACE_EXT_H_
+#define EIP207_RC_HW_INTERFACE_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Invalid (dummy) address
+#define EIP207_RC_RECORD_DUMMY_ADDRESS    0
+
+
+// Read/Write register constants
+
+// EIP-207s Classification Support module (p - number of the cache set)
+// Record Cache (FRC/TRC/ARC4RC) register interface
+#define EIP207_RC_REG_REGINDEX(base,p)  ((EIP207_REG_MAP_SIZE * p) + \
+                                         (base + \
+                                          (0x00 * EIP207_REG_OFFS)))
+#define EIP207_RC_REG_PARAMS(base,p)    ((EIP207_REG_MAP_SIZE * p) + \
+                                         ((base + EIP207_RC_REG_PARAMS_BASE) + \
+                                          (0x00 * EIP207_REG_OFFS)))
+#define EIP207_RC_REG_FREECHAIN(base,p) ((EIP207_REG_MAP_SIZE * p) + \
+                                         ((base + EIP207_RC_REG_PARAMS_BASE) + \
+                                          (0x01 * EIP207_REG_OFFS)))
+#define EIP207_RC_REG_PARAMS2(base,p)   ((EIP207_REG_MAP_SIZE * p) + \
+                                         ((base + EIP207_RC_REG_PARAMS_BASE) + \
+                                          (0x02 * EIP207_REG_OFFS)))
+#define EIP207_RC_REG_ECCCTRL(base,p)   ((EIP207_REG_MAP_SIZE * p) + \
+                                         ((base + EIP207_RC_REG_PARAMS_BASE) + \
+                                          (0x04 * EIP207_REG_OFFS)))
+
+// Debug counter registers (40 bit each, 2 consecutive words)
+#define EIP207_RC_REG_PREFEXEC(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0x80)
+#define EIP207_RC_REG_PREFBLCK(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0x88)
+#define EIP207_RC_REG_PREFDMA(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0x90)
+#define EIP207_RC_REG_SELOPS(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0x98)
+#define EIP207_RC_REG_SELDMA(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0xA0)
+#define EIP207_RC_REG_IDMAWR(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0xA8)
+#define EIP207_RC_REG_XDMAWR(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0xB0)
+#define EIP207_RC_REG_INVCMD(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0xB8)
+// Debug register, DMA read error status
+#define EIP207_RC_REG_RDMAERRFLGS_0(base,p) \
+    ((EIP207_REG_MAP_SIZE * p) + base + 0xD0)
+// Debug counter registers, (24 bits each)
+#define EIP207_RC_REG_RDMAERR(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0xE0)
+#define EIP207_RC_REG_WDMAERR(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0xE4)
+#define EIP207_RC_REG_INVECC(base,p)  ((EIP207_REG_MAP_SIZE * p) + base + 0xF0)
+#define EIP207_RC_REG_DATECC_CORR(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0xF4)
+#define EIP207_RC_REG_ADMECC_CORR(base,p) ((EIP207_REG_MAP_SIZE * p) + base + 0xE8)
+
+
+
+// Register default value
+#define EIP207_RC_REG_PARAMS_DEFAULT        0x00200401
+#define EIP207_RC_REG_PARAMS2_DEFAULT       0x00000000
+#define EIP207_RC_REG_REGINDEX_DEFAULT      0x00000000
+#define EIP207_RC_REG_ECCCRTL_DEFAULT       0x00000000
+
+
+
+
+#endif /* EIP207_RC_HW_INTERFACE_EXT_H_ */
+
+
+/* end of file eip207_rc_hw_interface_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_internal.h
new file mode 100644
index 0000000..5d85047
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_internal.h
@@ -0,0 +1,172 @@
+/* eip207_rc_internal.h
+ *
+ * EIP-207s Record Cache (RC) internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_RC_INTERNAL_H_
+#define EIP207_RC_INTERNAL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-207 Global Control Init API
+#include "eip207_global_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Record cache combination type
+typedef enum
+{
+    EIP207_RC_INTERNAL_NOT_COMBINED,        // Not combined
+    EIP207_RC_INTERNAL_FRC_TRC_COMBINED,    // TRC combined with FRC
+    EIP207_RC_INTERNAL_FRC_ARC4_COMBINED,   // ARC4RC combined with FRC
+    EIP207_RC_INTERNAL_TRC_ARC4_COMBINED    // ARC4RC combined with TRC
+} EIP207_RC_Internal_Combination_Type_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Init
+ *
+ * Initialize the EIP-207 Record Cache.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * CombinationType (input)
+ *      Specifies the Record Cache combination type with another one,
+ *      see EIP207_RC_Internal_Combination_Type_t
+ *
+ * CacheBase (input)
+ *      Base address of the Record Cache, must be one of the following:
+ *      EIP207_FRC_REG_BASE    - for the Flow Record Cache,
+ *      EIP207_TRC_REG_BASE    - for the Transform Record Cache,
+ *      EIP207_ARC4RC_REG_BASE - for the ARC4 Record Cache
+ *
+ * RC_Params_p (input, output)
+ *      Pointer to the memory location containing the Record Cache
+ *      initialization parameters.
+ *
+ * RecordWordCount (input)
+ *      Record Cache Record size in 32-bit words.
+ *
+ * Return code
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ */
+EIP207_Global_Error_t
+EIP207_RC_Internal_Init(
+        const Device_Handle_t Device,
+        const EIP207_RC_Internal_Combination_Type_t CombinationType,
+        const uint32_t CacheBase,
+        EIP207_Global_CacheParams_t * RC_Params_p,
+        const unsigned int RecordWordCount);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Status_Get
+ *
+ * Get the EIP-207 Record Cache status.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * CacheSetId (input)
+ *      Cache set identifier.
+ *
+ * FRC_Status_p (output)
+ *      Pointer to the memory location to store the Flow Record Cache
+ *      status information.
+ *
+ * TRC_Status_p (output)
+ *      Pointer to the memory location to store the Transform Record Cache
+ *      status information.
+ *
+ * ARC4RC_Status_p (output)
+ *      Pointer to the memory location to store the ARC4 Record Cache
+ *      status information.
+ *
+ * Return code
+ *     None
+ */
+void
+EIP207_RC_Internal_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CacheSetId,
+        EIP207_Global_CacheStatus_t * const FRC_Status_p,
+        EIP207_Global_CacheStatus_t * const TRC_Status_p,
+        EIP207_Global_CacheStatus_t * const ARC4RC_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_DebugStatistics_Get
+ *
+ * Get the EIP-207 Record Cache debug statistics.
+ *
+ * Device (input)
+ *      Device handle that identifies the Record Cache hardware
+ *
+ * CacheSetId (input)
+ *      Cache set identifier.
+ *
+ * FRC_Stats_p (output)
+ *      Pointer to the memory location to store the Flow Record Cache
+ *      status information.
+ *
+ * TRC_Stats_p (output)
+ *      Pointer to the memory location to store the Transform Record Cache
+ *      statistics information.
+ *
+ * Return code
+ *     None
+ */
+void
+EIP207_RC_Internal_DebugStatistics_Get(
+        const Device_Handle_t Device,
+        const unsigned int CacheSetId,
+        EIP207_Global_CacheDebugStatistics_t * const FRC_Stats_p,
+        EIP207_Global_CacheDebugStatistics_t * const TRC_Stats_p);
+
+/* end of file eip207_rc_internal.h */
+
+
+#endif /* EIP207_RC_INTERNAL_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_level0_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_level0_ext.h
new file mode 100644
index 0000000..f7dfb63
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_rc_level0_ext.h
@@ -0,0 +1,268 @@
+/* eip207_rc_level0_ext.h
+ *
+ * EIP-207 Record Cache Level0 Internal interface High-Performance (HP)
+ * extensions
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_RC_LEVEL0_EXT_H_
+#define EIP207_RC_LEVEL0_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // BIT definitions, bool, uint32_t
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"    // EIP207_RC_REG_*
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207 Global Register Write/Read Functions
+ *
+ */
+
+static inline void
+EIP207_RC_PARAMS_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const bool fSWReset,
+        const bool fBlock,
+        const bool fDataAccess,
+        const uint8_t HashTableMask,
+        const uint8_t BlockClockCount,
+        const bool fMaxRecSize,
+        const uint16_t RecordWordCount)
+{
+    uint32_t RegVal = EIP207_RC_REG_PARAMS_DEFAULT;
+
+    IDENTIFIER_NOT_USED(fMaxRecSize);
+
+    if (!fSWReset)
+        RegVal &= (~BIT_0);
+
+    if (fBlock)
+        RegVal |= BIT_1;
+
+    if (fDataAccess)
+        RegVal |= BIT_2;
+
+    RegVal &= (~((uint32_t)(MASK_9_BITS << 18)));
+    RegVal |= (uint32_t)((((uint32_t)RecordWordCount) & MASK_9_BITS) << 18);
+
+    RegVal &= (~((uint32_t)(MASK_3_BITS << 10)));
+    RegVal |= (uint32_t)((((uint32_t)BlockClockCount) & MASK_3_BITS) << 10);
+
+    RegVal |= (uint32_t)((((uint32_t)HashTableMask)   & MASK_3_BITS) << 4);
+
+    EIP207_Write32(Device, EIP207_RC_REG_PARAMS(CacheBase, CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_PARAMS_RD(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        bool * const fDMAReadError_p,
+        bool * const fDMAWriteError_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_RC_REG_PARAMS(CacheBase, CacheNr));
+
+    *fDMAReadError_p  = ((RegVal & BIT_30) != 0);
+    *fDMAWriteError_p = ((RegVal & BIT_31) != 0);
+}
+
+
+static inline void
+EIP207_RC_FREECHAIN_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint16_t HeadOffset,
+        const uint16_t TailOffset)
+{
+    uint32_t RegVal = EIP207_RC_REG_PARAMS2_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)TailOffset) & MASK_10_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)HeadOffset) & MASK_10_BITS));
+
+    EIP207_Write32(Device, EIP207_RC_REG_FREECHAIN(CacheBase,CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_PARAMS2_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint16_t HashTableStart,
+        const uint16_t Record2WordCount,
+        const uint8_t DMAWrCombDly)
+{
+    uint32_t RegVal = EIP207_RC_REG_PARAMS2_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)Record2WordCount) & MASK_9_BITS) << 18);
+    RegVal |= (uint32_t)((((uint32_t)DMAWrCombDly)     & MASK_8_BITS) << 10);
+    RegVal |= (uint32_t)((((uint32_t)HashTableStart)   & MASK_10_BITS));
+
+    EIP207_Write32(Device, EIP207_RC_REG_PARAMS2(CacheBase, CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_REGINDEX_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint8_t Regindex)
+{
+    uint32_t RegVal = EIP207_RC_REG_REGINDEX_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)Regindex) & MASK_6_BITS));
+
+    EIP207_Write32(Device, EIP207_RC_REG_REGINDEX(CacheBase, CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_ECCCTRL_WR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const bool fDataEccOflo,
+        const bool fDataEccErr,
+        const bool fAdminEccErr)
+{
+    uint32_t RegVal = EIP207_RC_REG_ECCCRTL_DEFAULT;
+
+    if (fDataEccOflo)
+        RegVal |= BIT_29;
+
+    if (fDataEccErr)
+        RegVal |= BIT_30;
+
+    if (fAdminEccErr)
+        RegVal |= BIT_31;
+
+    EIP207_Write32(Device, EIP207_RC_REG_ECCCTRL(CacheBase, CacheNr), RegVal);
+}
+
+
+static inline void
+EIP207_RC_ECCCTRL_RD_CLEAR(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        bool * const fDataEccOflo_p,
+        bool * const fDataEccErr_p,
+        bool * const fAdminEccErr_p)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP207_Read32(Device, EIP207_RC_REG_ECCCTRL(CacheBase, CacheNr));
+
+    *fDataEccOflo_p  = ((RegVal & BIT_29) != 0);
+    *fDataEccErr_p   = ((RegVal & BIT_30) != 0);
+    *fAdminEccErr_p  = ((RegVal & BIT_31) != 0);
+
+    // Clear non-correctable (but non-fatal) RC Data RAM ECC error if detected
+    if (*fDataEccErr_p)
+    {
+        // *fDataEccOflo_p:
+        // Do not clear fatal RC Data RAM non-correctable error here
+
+        // *fAdminEccErr_p:
+        // Do not clear fatal RC Administration RAM non-correctable error here
+
+        // Do not clear anything in admin_corr_mask
+        RegVal &= (~MASK_12_BITS);
+
+        if(*fDataEccErr_p)
+            RegVal &= (~BIT_30); // Write 0 to clear the error '1' status bit
+
+        EIP207_Write32(Device,
+                       EIP207_RC_REG_ECCCTRL(CacheBase, CacheNr),
+                       RegVal);
+    }
+}
+
+static inline void
+EIP207_RC_LONGCTR_RD(
+        const Device_Handle_t Device,
+        unsigned int RegOffset,
+        uint64_t *Counter)
+{
+    uint32_t val_lo, val_hi;
+    val_lo = EIP207_Read32(Device, RegOffset);
+    val_hi = EIP207_Read32(Device, RegOffset + 4) & MASK_8_BITS;
+
+    *Counter = (((uint64_t) val_hi) << 32) | val_lo;
+}
+
+static inline void
+EIP207_RC_SHORTCTR_RD(
+        const Device_Handle_t Device,
+        unsigned int RegOffset,
+        uint32_t *Counter)
+{
+    *Counter = EIP207_Read32(Device, RegOffset) & MASK_24_BITS;
+}
+
+static inline void
+EIP207_RC_RDMAERRFLGS_RD(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        uint32_t *ErrFlags)
+{
+    *ErrFlags = EIP207_Read32(Device,
+                              EIP207_RC_REG_RDMAERRFLGS_0(CacheBase,CacheNr)) &
+                             MASK_8_BITS;
+}
+
+#endif /* EIP207_RC_LEVEL0_EXT_H_ */
+
+/* end of file eip207_rc_level0_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_support.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_support.h
new file mode 100644
index 0000000..dee004e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip207_support.h
@@ -0,0 +1,69 @@
+/* eip207_support.h
+ *
+ * EIP-207 Support interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP207_SUPPORT_H_
+#define EIP207_SUPPORT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-207 Global Control Init API
+#include "eip207_global_init.h"         // EIP207_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Read64
+ */
+EIP207_Global_Error_t
+EIP207_Global_Read64(
+        const Device_Handle_t Device,
+        const unsigned int Value64_OffsetLo,
+        const unsigned int Value64_OffsetHi,
+        EIP207_Global_Value64_t * const Value64_p);
+
+
+/* end of file eip207_support.h */
+
+
+#endif /* EIP207_SUPPORT_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74.h
new file mode 100644
index 0000000..6688022
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74.h
@@ -0,0 +1,464 @@
+/* eip74.h
+ *
+ * EIP-74 Driver Library API:
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef EIP74_H_
+#define EIP74_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+/*----------------------------------------------------------------------------
+ * Example API Use Order:
+ *
+ * 1 Call EIP74_Init to initialize the IOArea of the Driver Library.
+ *
+ * 2 Call EIP74_Configure to set the configuration parameters of the device:
+ *   the generate block size and the reseed thresholds. This function can be
+ *   called anywhere between step 1 and step 5. Typically these configuration
+ *   parameters are set only once.
+ *
+ * 3 Call EIP74_Reset to reset the device. It it returns EIP74_NO_ERROR
+ *   go to step 5, if it returns EIP74_BUSY_RETRY_LATER, go to step 4.
+ *
+ * 4 Call EIP74_Reset_Isdone until the result is EIP74_NO_ERROR.
+ *
+ * 5 Call EIP74_Instantiate. When this function returns, the device is
+ *   operational.
+ *
+ * Steps 3 through 5 can be repeated to re-instantiate the DRBG, but typically
+ * these steps are performed only once,
+ *
+ * 6 Periodically, or upon receiving a device interrupt, check the
+ *   status of the device and take necessary actions.
+ *
+ * 6.1 call EIP74_Status_Get to find out what events occurred.
+ *
+ * 6.2 If a stuck-output fault occurred, call EIP74_Clear to clear the fault
+ *     condition. Stuck-output faults are very rare but not impossible during
+ *     normal operation.
+ *
+ * 6.3 If a reseed warning occurred, call EIP74_Reseed
+ *
+ * 7 Optionally call EIP74_Reset to stop operation of the device.
+ */
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP74_IOAREA_REQUIRED_SIZE       (2 * sizeof(void*))
+
+/*----------------------------------------------------------------------------
+ * EIP74_Error_t
+ *
+ * Status (error) code type returned by these API functions
+ * See each function "Return value" for details.
+ *
+ * EIP74_NO_ERROR : successful completion of the call.
+ * EIP74_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ * EIP74_ARGUMENT_ERROR :  invalid argument for a function parameter.
+ * EIP74_BUSY_RETRY_LATER : Device is busy.
+ * EIP74_ILLEGAL_IN_STATE : illegal state transition
+ */
+typedef enum
+{
+    EIP74_NO_ERROR = 0,
+    EIP74_UNSUPPORTED_FEATURE_ERROR,
+    EIP74_ARGUMENT_ERROR,
+    EIP74_BUSY_RETRY_LATER,
+    EIP74_ILLEGAL_IN_STATE
+} EIP74_Error_t;
+
+// Generic EIP HW version
+typedef struct
+{
+    // The basic EIP number.
+    uint8_t EipNumber;
+
+    // The complement of the basic EIP number.
+    uint8_t ComplmtEipNumber;
+
+    // Hardware Patch Level.
+    uint8_t HWPatchLevel;
+
+    // Minor Hardware revision.
+    uint8_t MinHWRevision;
+
+    // Major Hardware revision.
+    uint8_t MajHWRevision;
+} EIP_Version_t;
+
+// EIP-74 HW options
+typedef struct
+{
+    // Number of client interfaces
+    uint8_t ClientCount;
+
+    // Number of AES cores
+    uint8_t AESCoreCount;
+
+    // Speed grade of AES core
+    uint8_t AESSpeed;
+
+    // Depth of output FIFO
+    uint8_t FIFODepth;
+} EIP74_Options_t;
+
+
+// EIP-74 Hardware capabilities.
+typedef struct
+{
+    EIP_Version_t HW_Revision;
+    EIP74_Options_t HW_Options;
+} EIP74_Capabilities_t;
+
+// Configuration parameters for EIP-74.
+typedef struct
+{
+    // Number of IVs generated for each Generate operation.
+    unsigned int GenerateBlockSize;
+
+    // Number of Generate operations after which it is an error to continue
+    // without reseed
+    unsigned int ReseedThr;
+
+    // Number of Generate operations after which to notify that reseed is
+    // required
+    unsigned int ReseedThrEarly;
+} EIP74_Configuration_t;
+
+
+// Status information of the EIP-74.
+typedef struct
+{
+    // Number of generate operations since last initialize or reseed
+    unsigned int GenerateBlockCount;
+
+    // Stuck-output fault detected
+    bool fStuckOut;
+
+    // Not-initialized error detected
+    bool fNotInitialized;
+
+    // Reseed error  detected, GenerateBlockCount passed threshold
+    bool fReseedError;
+
+    // Reseed warning detected, GenerateBlockCount passed early threshold
+    bool fReseedWarning;
+
+    // DRBG was instantiated successfully
+    bool fInstantiated;
+
+    // Number of IVs available
+    unsigned int AvailableCount;
+} EIP74_Status_t;
+
+
+// place holder for device specific internal data
+typedef struct
+{
+    uint32_t placeholder[EIP74_IOAREA_REQUIRED_SIZE];
+} EIP74_IOArea_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Init
+ *
+ * This function performs the initialization of the EIP-74 HW
+ * interface and transits the API to the Initialized state.
+ *
+ * This function returns the EIP74_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Driver Library configuration
+ * and the EIP-74 HW revision or configuration.
+ *
+ * Note: This function should be called first.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Device (input)
+ *     Handle for the Global Control device instance returned by Device_Find.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Init(
+        EIP74_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset
+ *
+ * This function starts the EIP-74 Reset operation. If the reset operation
+ * can be done immediately this function returns EIP74_NO_ERROR.
+ * Otherwise it will return EIP74_BUSY_RETRY_LATER indicating
+ * that the reset operation has been started and is ongoing.
+ * The EIP74_Reset_IsDone() function can be used to poll the device
+ * for the completion of the reset operation.
+ *
+ * Note: This function must be called and the operation must be complete
+ *       before calling the EIP74_Instantiate() function
+ * Note: This function can be used to terminate operation of the DRBG. This
+ *       will also clear the internal state of the hardware.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * This function can be called once the driver library is initialized.
+ *
+ * This function is NOT re-entrant. It can be called concurrently with
+ * EIP74_HWRevision_Get, EIP74_Configure, EIP174_Status_Get and EIP74_Clear.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : Global SW Reset is done
+ *     EIP74_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP74_BUSY_RETRY_LATER: Global SW Reset is started but
+ *                                    not completed yet
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Reset(
+        EIP74_IOArea_t * const IOArea_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset_IsDone
+ *
+ * This function checks the status of the started by the EIP74_Reset()
+ * function for the EIP-74 device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * This function can be called after a call to EIP74_Reset and before any
+ * subsequent call to EIP74_Instantiate
+ *
+ * This function is NOT re-entrant. It can be called concurrently with
+ * EIP74_HWRevision_Get, EIP74_Configure, EIP174_Status_Get and EIP74_Clear.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : Global SW Reset operation is done
+ *     EIP74_BUSY_RETRY_LATER: Global SW Reset is started but
+ *                                    not completed yet
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Reset_IsDone(
+        EIP74_IOArea_t * const IOArea_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_HWRevision_Get
+ *
+ * This function returns EIP-74 hardware revision
+ * information in the Capabilities_p data structure.
+ *
+ * Device (input)
+ *     Handle of the device to be used.
+ *
+ * Capabilities_p (output)
+ *     Pointer to the place holder in memory where the device capability
+ *     information will be stored.
+ *
+ * This function can be called at all times, even when the device is
+ * not initialized.
+ *
+ * This function is re-entrant and can be called
+ * concurrently with other driver library functions..
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ */
+EIP74_Error_t
+EIP74_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP74_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Configure
+ *
+ * This function configures the block size and the reseed thresholds of the
+ * EIP-74 hardware. If called, it should be called before the first
+ * call to EIP74_Reset or between EIP74_Reset and EIP74_Instantiate.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Configuration_p (input)
+ *     Pointer to the data structure that contains the EIP74 configuration
+ *
+ * This function can be called once the driver library is initialized.
+ *
+ * This function is NOT re-entrant. It can be called concurrently
+ * with other driver library functions.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Configure(
+        EIP74_IOArea_t * const IOArea_p,
+        const EIP74_Configuration_t * const Configuration_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Instantiate
+ *
+ * This function instantiates the AES-256-CTR SP800-90 DRBG on the EIP-74
+ * hardware. It can be called after a reset operation that is completed.
+ * After instantiation, the EIP-74 will generate pseudo-random data blocks
+ * of the configured size autonomously.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 12 32-bit worfs that serves as the
+ *     entropy to instantiate the DRBG.
+ *
+ * fStuckOut (input)
+ *     Enable stuck-output detection (next output is the same as previous)
+ *     during IV generation.
+ *
+ * This function can be called after EIP74_Reset or EIP74_Reset_IsDone when
+ * such function returns EIP74_NO_ERROR.
+ *
+ * This function is NOT re-entrant. It can be called concurrently with
+ * EIP74_HWRevision_Get, EIP74_Configure, EIP174_Status_Get and EIP74_Clear.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Instantiate(
+        EIP74_IOArea_t * const IOArea_p,
+        const uint32_t * const Entropy_p,
+        bool fStuckOut);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reseed
+ *
+ * This function initiates a reseed operation of the DRBG. The reseed
+ * will take effect when the next Generate operation is started.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 12 32-bit worfs that serves as the
+ *     entropy to reseed the DRBG.
+ *
+ * This function can be called after EIP7_Instantiate and before any
+ * subsequent call to EIP74_Reset.
+ *
+ * This function is NOT re-entrant. It can be called concurrently with
+ * EIP74_HWRevision_Get, EIP74_Configure, EIP174_Status_Get and EIP74_Clear.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Reseed(
+        EIP74_IOArea_t * const IOArea_p,
+        const uint32_t * const Entropy_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Status_Get
+ *
+ * This function reads the status of the EIP-74.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Status_p (output)
+ *     Status information obtained from the EIP-74.
+ *
+ * This function can be called once the driver library is initialized.
+ *
+ * This function is re-entrant and can be called
+ * concurrently with other driver library functions.
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Status_Get(
+        EIP74_IOArea_t * const IOArea_p,
+        EIP74_Status_t * const Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Clear
+ *
+ * This function clears any stuck-output fault condition that may have
+ * been detected by the hardware.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * This function can be called once the driver library is initialized.
+ *
+ * This function is re-entrant and can be called
+ * concurrently with other driver library functions..
+ *
+ * Return value
+ *     EIP74_NO_ERROR : operation is completed
+ *     EIP74_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP74_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP74_Error_t
+EIP74_Clear(
+        EIP74_IOArea_t * const IOArea_p);
+
+
+#endif /* EIP74_H_ */
+
+
+/* end of file eip74.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_hw_interface.h
new file mode 100644
index 0000000..2ea1909
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_hw_interface.h
@@ -0,0 +1,90 @@
+/* eip74_hw_interface.h
+ *
+ * EIP74 register internal interface.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef EIP74_HW_INTERFACE_H_
+#define EIP74_HW_INTERFACE_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-74 TRNG device EIP number (0x4A) and complement (0xB5)
+#define EIP74_SIGNATURE                   ((uint16_t)0xB54A)
+
+// Byte offsets of the EIP74 registers
+#define EIP74_REG_OFFS    4
+
+#define EIP74_REG_INPUT_0         (0x00 * EIP74_REG_OFFS)
+#define EIP74_REG_INPUT_1         (0x01 * EIP74_REG_OFFS)
+#define EIP74_REG_INPUT_2         (0x02 * EIP74_REG_OFFS)
+#define EIP74_REG_INPUT_3         (0x03 * EIP74_REG_OFFS)
+#define EIP74_REG_OUTPUT_0        (0x00 * EIP74_REG_OFFS)
+#define EIP74_REG_OUTPUT_1        (0x01 * EIP74_REG_OFFS)
+#define EIP74_REG_OUTPUT_2        (0x02 * EIP74_REG_OFFS)
+#define EIP74_REG_OUTPUT_3        (0x03 * EIP74_REG_OFFS)
+#define EIP74_REG_STATUS          (0x04 * EIP74_REG_OFFS)
+#define EIP74_REG_INTACK          (0x04 * EIP74_REG_OFFS)
+#define EIP74_REG_CONTROL         (0x05 * EIP74_REG_OFFS)
+#define EIP74_REG_GENERATE_CNT    (0x08 * EIP74_REG_OFFS)
+#define EIP74_REG_RESEED_THR_EARLY (0x09 * EIP74_REG_OFFS)
+#define EIP74_REG_RESEED_THR      (0x0A * EIP74_REG_OFFS)
+#define EIP74_REG_GEN_BLK_SIZE    (0x0B * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_0           (0x10 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_1           (0x11 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_2           (0x12 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_3           (0x13 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_4           (0x14 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_5           (0x15 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_6           (0x16 * EIP74_REG_OFFS)
+#define EIP74_REG_KEY_7           (0x17 * EIP74_REG_OFFS)
+#define EIP74_REG_PS_AI_0         (0x10 * EIP74_REG_OFFS)
+#define EIP74_REG_TEST            (0x1C * EIP74_REG_OFFS)
+#define EIP74_REG_OPTIONS         (0x1E * EIP74_REG_OFFS)
+#define EIP74_REG_VERSION         (0x1F * EIP74_REG_OFFS)
+
+// Default (reset) register values
+// Note: when updating the default register values from 0 to something else
+//       check how this value is used in the corresponding level0 macro,
+//       it may need to be updated too for the boolean operations!
+#define EIP74_REG_INTACK_DEFAULT  0x00000000
+#define EIP74_REG_CONTROL_DEFAULT 0x00000000
+#define EIP74_REG_GEN_BLK_CNT_DEFAULT 0x00000000
+#define EIP74_REG_TEST_DEFAULT    0x00000000
+
+#endif /* EIP74_HW_INTERFACE_H_*/
+
+/* end of file eip74_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_level0.h
new file mode 100644
index 0000000..69a1dd2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip74_level0.h
@@ -0,0 +1,397 @@
+/* eip74_level0.h
+ *
+ * This file contains all the macros and functions that allow
+ * access to the EIP74 registers and to build the values
+ * read or written to the registers.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef EIP74_LEVEL0_H_
+#define EIP74_LEVEL0_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip74.h"
+
+// Register addresses
+#include "eip74_hw_interface.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Read32
+ *
+ * This routine writes to a Register location in the EIP74.
+ */
+static inline uint32_t
+EIP74_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Write32
+ *
+ * This routine writes to a Register location in the EIP74.
+ */
+static inline void
+EIP74_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline void
+EIP74_INPUT_WR(
+        Device_Handle_t Device,
+        const uint32_t * const Input_p)
+{
+    unsigned i;
+    for (i=0; i<4; i++)
+    {
+        EIP74_Write32(Device,
+                      EIP74_REG_INPUT_0 + i*sizeof(uint32_t),
+                      Input_p[i]);
+    }
+}
+
+static inline void
+EIP74_OUTPUT_RD(
+        Device_Handle_t Device,
+        uint32_t * const Output_p)
+{
+    unsigned i;
+    for (i=0; i<4; i++)
+    {
+        Output_p[i] =
+            EIP74_Read32(Device, EIP74_REG_OUTPUT_0 + i*sizeof(uint32_t));
+    }
+}
+
+
+static inline void
+EIP74_CONTROL_WR(
+        Device_Handle_t Device,
+        const bool fReadyMask,
+        const bool fStuckOutMask,
+        const bool fTestMode,
+        const bool fHostMode,
+        const bool fEnableDRBG,
+        const bool fForceStuckOut,
+        const bool fRequestData,
+        const uint16_t DataBlocks)
+{
+    uint32_t RegVal = EIP74_REG_CONTROL_DEFAULT;
+
+    if (fRequestData)
+    {   // RequestData bit leaves all other control settings unchanged.
+        RegVal |= BIT_16;
+        RegVal |= (DataBlocks & MASK_12_BITS) << 20;
+    }
+    else
+    {
+        if (fReadyMask)
+            RegVal |= BIT_0;
+
+        if (fStuckOutMask)
+            RegVal |= BIT_2;
+
+        if (fTestMode)
+            RegVal |= BIT_8;
+
+        if (fHostMode)
+            RegVal |= BIT_9;
+
+        if (fEnableDRBG)
+            RegVal |= BIT_10;
+
+        if (fForceStuckOut)
+            RegVal |= BIT_11;
+    }
+
+
+    EIP74_Write32(Device, EIP74_REG_CONTROL, RegVal);
+}
+
+
+static inline void
+EIP74_CONTROL_RD(
+        Device_Handle_t Device,
+        bool * const fReseed)
+{
+    uint32_t RegVal = EIP74_Read32(Device, EIP74_REG_CONTROL);
+
+    *fReseed = (RegVal & BIT_15) != 0;
+}
+
+
+static inline void
+EIP74_STATUS_RD(
+        Device_Handle_t Device,
+        bool * const fReady,
+        bool * const fPSAIWriteOK,
+        bool * const fStuckOut,
+        bool * const fEarlyReseed,
+        bool * const fTestReady,
+        bool * const fGenPktError,
+        bool * const fInstantiated,
+        bool * const fTestStuckOut,
+        uint8_t * const BlocksAvailable,
+        bool * const fNeedClock)
+{
+    uint32_t RegVal =  EIP74_Read32(Device, EIP74_REG_STATUS);
+
+    *fReady          = (RegVal & BIT_0) != 0;
+    *fPSAIWriteOK    = (RegVal & BIT_1) != 0;
+    *fStuckOut       = (RegVal & BIT_2) != 0;
+    *fEarlyReseed    = (RegVal & BIT_7) != 0;
+    *fTestReady      = (RegVal & BIT_8) != 0;
+    *fGenPktError    = (RegVal & BIT_9) != 0;
+    *fInstantiated   = (RegVal & BIT_10) != 0;
+    *fTestStuckOut   = (RegVal & BIT_15) != 0;
+
+    *BlocksAvailable = (RegVal >> 16) & MASK_8_BITS;
+
+    *fNeedClock      = (RegVal & BIT_31) != 0;
+}
+
+
+/* Write TRNG_INTACK register (write-only) */
+static inline void
+EIP74_INTACK_WR(
+        Device_Handle_t Device,
+        const bool fReadyAck,
+        const bool fStuckOutAck,
+        const bool fTestStuckOut)
+{
+    uint32_t RegVal = EIP74_REG_INTACK_DEFAULT;
+
+    if (fReadyAck)
+        RegVal |= BIT_0;
+
+    if (fStuckOutAck)
+        RegVal |= BIT_2;
+
+    if (fTestStuckOut)
+        RegVal |= BIT_15;
+
+    EIP74_Write32(Device, EIP74_REG_INTACK, RegVal);
+}
+
+
+static inline void
+EIP74_GENERATE_CNT_RD(
+        Device_Handle_t Device,
+        uint32_t * const Value_p)
+{
+    *Value_p = EIP74_Read32(Device, EIP74_REG_GENERATE_CNT);
+}
+
+
+static inline void
+EIP74_RESEED_THR_WR(
+        Device_Handle_t Device,
+        const uint32_t Value)
+{
+    EIP74_Write32(Device, EIP74_REG_RESEED_THR, Value);
+}
+
+
+static inline void
+EIP74_RESEED_THR_RD(
+        Device_Handle_t Device,
+        uint32_t * const Value)
+{
+    *Value = EIP74_Read32(Device, EIP74_REG_RESEED_THR);
+}
+
+
+static inline void
+EIP74_RESEED_THR_EARLY_WR(
+        Device_Handle_t Device,
+        const uint32_t Value)
+{
+    EIP74_Write32(Device, EIP74_REG_RESEED_THR_EARLY, Value);
+}
+
+
+static inline void
+EIP74_RESEED_THR_EARLY_RD(
+        Device_Handle_t Device,
+        uint32_t * const Value)
+{
+    *Value = EIP74_Read32(Device, EIP74_REG_RESEED_THR_EARLY);
+}
+
+
+static inline void
+EIP74_GEN_BLK_SIZE_WR(
+        Device_Handle_t Device,
+        const uint32_t Value)
+{
+    uint32_t RegVal = EIP74_REG_GEN_BLK_CNT_DEFAULT;
+
+    RegVal |= Value & MASK_12_BITS;
+    EIP74_Write32(Device, EIP74_REG_GEN_BLK_SIZE, RegVal);
+}
+
+
+static inline bool
+EIP74_REV_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP74_SIGNATURE);
+}
+
+
+static inline void
+EIP74_VERSION_RD(
+        Device_Handle_t Device,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP74_Read32(Device, EIP74_REG_VERSION);
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & 0x0f);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & 0x0f);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & 0x0f);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & 0xff);
+    *EipNumber         = (uint8_t)((RevRegVal)       & 0xff);
+}
+
+
+static inline void
+EIP74_OPTIONS_RD(
+        Device_Handle_t Device,
+        uint8_t * const ClientCount,
+        uint8_t * const AESCoreCount,
+        uint8_t * const AESCoreSpeed,
+        uint8_t * const FIFODepth)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP74_Read32(Device, EIP74_REG_OPTIONS);
+
+    *ClientCount = RegVal & MASK_6_BITS;
+    *AESCoreCount = (RegVal >> 8) & MASK_2_BITS;
+    *AESCoreSpeed = (RegVal >> 10) & MASK_2_BITS;
+    *FIFODepth = (RegVal >> 16) & MASK_8_BITS;
+}
+
+
+/* Write TRNG_TEST register */
+static inline void
+EIP74_TEST_WR(
+        Device_Handle_t Device,
+        const bool fTestAES256,
+        const bool fTestSP80090,
+        const bool fTestIRQ)
+{
+    uint32_t Value = EIP74_REG_TEST_DEFAULT;
+
+    if (fTestAES256)
+        Value |= BIT_6;
+
+    if (fTestSP80090)
+        Value |= BIT_7;
+
+    if (fTestIRQ)
+        Value |= BIT_31;
+
+    EIP74_Write32(Device, EIP74_REG_TEST, Value);
+}
+
+
+/* Read TRNG_TEST register */
+static inline void
+EIP74_TEST_RD(
+        Device_Handle_t Device,
+        bool * const fTestAES256,
+        bool * const fTestSP80090,
+        bool * const fTestIRQ)
+{
+    uint32_t Value = EIP74_Read32(Device, EIP74_REG_TEST);
+
+    *fTestAES256 = (Value & BIT_6) != 0;
+    *fTestSP80090 = (Value & BIT_7) != 0;
+    *fTestIRQ = (Value & BIT_31) != 0;
+}
+
+
+/* Write Key registers */
+static inline void
+EIP74_KEY_WR(
+        Device_Handle_t Device,
+        const uint32_t * Data_p,
+        const unsigned int WordCount)
+{
+    unsigned int i;
+
+    for(i = 0; i < WordCount; i++)
+        EIP74_Write32(Device,
+                      EIP74_REG_KEY_0 + i * sizeof(uint32_t),
+                      Data_p[i]);
+}
+
+
+/* Write PS_AI registers */
+static inline void
+EIP74_PS_AI_WR(
+        Device_Handle_t Device,
+        const uint32_t * Data_p,
+        const unsigned int WordCount)
+{
+    unsigned int i;
+
+    for(i = 0; i < WordCount; i++)
+        EIP74_Write32(Device,
+                      EIP74_REG_PS_AI_0 + i * sizeof(uint32_t),
+                      Data_p[i]);
+}
+
+
+#endif /* EIP74_LEVEL0_H_ */
+
+/* end of file eip74_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_hw_interface.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_hw_interface.h
new file mode 100644
index 0000000..08a390f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_hw_interface.h
@@ -0,0 +1,151 @@
+/* eip96_hw_interface.h
+ *
+ * EIP-96 Packet Engine HW interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP96_HW_INTERFACE_H_
+#define EIP96_HW_INTERFACE_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip96.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Internal Packet Engine time-out – a fatal error requiring a complete reset.
+#define EIP96_TIMEOUT_FATAL_ERROR_MASK     BIT_14
+
+// Read/Write register constants
+
+/*****************************************************************************
+ * Byte offsets of the EIP-96 Packet Engine registers
+ *****************************************************************************/
+#define EIP96_REG_OFFS                     4
+#define EIP96_REG_MAP_SIZE                 8192
+
+// Processing Packet Engine n (n - number of the DSE thread)
+#define EIP96_REG_TOKEN_CTRL_STAT(n)       ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x00 * EIP96_REG_OFFS)))
+#define EIP96_REG_FUNCTION_EN(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x01 * EIP96_REG_OFFS)))
+#define EIP96_REG_CONTEXT_CTRL(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x02 * EIP96_REG_OFFS)))
+#define EIP96_REG_CONTEXT_STAT(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x03 * EIP96_REG_OFFS)))
+
+#define EIP96_REG_OUT_TRANS_CTRL_STAT(n)   ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x06 * EIP96_REG_OFFS)))
+#define EIP96_REG_OUT_BUF_CTRL(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x07 * EIP96_REG_OFFS)))
+#define EIP96_REG_CTX_NUM32_THR(n)         ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x08 * EIP96_REG_OFFS)))
+#define EIP96_REG_CTX_NUM64_THR_L(n)       ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x09 * EIP96_REG_OFFS)))
+#define EIP96_REG_CTX_NUM64_THR_H(n)       ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x0a * EIP96_REG_OFFS)))
+#define EIP96_REG_TOKEN_CTRL2(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + \
+                                             (0x0b * EIP96_REG_OFFS)))
+
+// EIP-96 PRNG
+#define EIP96_REG_PRNG_STAT(n)             ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x00 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_CTRL(n)             ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x01 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_SEED_L(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x02 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_SEED_H(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x03 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_KEY_0_L(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x04 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_KEY_0_H(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x05 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_KEY_1_L(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                             ((EIP96_PRNG_BASE) + \
+                                              (0x06 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_KEY_1_H(n)          ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x07 * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_LFSR_L(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x0c * EIP96_REG_OFFS)))
+#define EIP96_REG_PRNG_LFSR_H(n)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_PRNG_BASE) + \
+                                             (0x0d * EIP96_REG_OFFS)))
+
+#define EIP96_REG_ECN_TABLE(n,k)           ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_CONF_BASE) + 0x3e0 + 4*(k)))
+
+// EIP-96 Options and Version
+// New registers to must still be added to the HW,
+// do not use these registers yet
+#define EIP96_REG_OPTIONS(n)               ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_VER_BASE) + \
+                                             (0x00 * EIP96_REG_OFFS)))
+#define EIP96_REG_VERSION(n)               ((EIP96_REG_MAP_SIZE * n) + \
+                                            ((EIP96_VER_BASE) + \
+                                             (0x01 * EIP96_REG_OFFS)))
+
+// Default EIP96_REG_TOKEN_CTRL_STAT register value
+#define EIP96_REG_TOKEN_CTRL_STAT_DEFAULT   0x00004004
+
+// Default EIP96_REG_PRNG_CTRL register value
+#define EIP96_REG_PRNG_CTRL_DEFAULT         0x00000000
+
+// Default EIP96_REG_OUT_BUF_CTRL register value
+#define EIP96_REG_OUT_BUF_CTRL_DEFAULT      0x00000000
+
+
+#endif /* EIP96_HW_INTERFACE_H_ */
+
+
+/* end of file eip96_hw_interface.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_level0.h
new file mode 100644
index 0000000..78c96d7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip96_level0.h
@@ -0,0 +1,546 @@
+/* eip96_level0.h
+ *
+ * EIP-96 Packet Engine Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP96_LEVEL0_H_
+#define EIP96_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// EIP-96 Packet Engine HW interface
+#include "eip96_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP96_Read32
+ *
+ * This routine writes to a Register location in the EIP-96.
+ */
+static inline uint32_t
+EIP96_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP96_Write32
+ *
+ * This routine writes to a Register location in the EIP-96.
+ */
+static inline void
+EIP96_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline void
+EIP96_EIP_REV_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP96_Read32(Device, EIP96_REG_VERSION(PEnr));
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);;
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP96_OPTIONS_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        bool * const fAES,
+        bool * const fAESfb,
+        bool * const fAESspeed,
+        bool * const fDES,
+        bool * const fDESfb,
+        bool * const fDESspeed,
+        uint8_t * const ARC4,
+        bool * const fAES_XTS,
+        bool * const fWireless,
+        bool * const fMD5,
+        bool * const fSHA1,
+        bool * const fSHA1speed,
+        bool * const fSHA224_256,
+        bool * const fSHA384_512,
+        bool * const fXCBC_MAC,
+        bool * const fCBC_MACspeed,
+        bool * const fCBC_MACkeylens,
+        bool * const fGHASH)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP96_Read32(Device, EIP96_REG_OPTIONS(PEnr));
+
+    *fGHASH           = ((RegVal & BIT_30) != 0);
+    *fCBC_MACkeylens  = ((RegVal & BIT_29) != 0);
+    *fCBC_MACspeed    = ((RegVal & BIT_28) != 0);
+    *fXCBC_MAC        = ((RegVal & BIT_27) != 0);
+    *fSHA384_512      = ((RegVal & BIT_26) != 0);
+    *fSHA224_256      = ((RegVal & BIT_25) != 0);
+    *fSHA1speed       = ((RegVal & BIT_24) != 0);
+    *fSHA1            = ((RegVal & BIT_23) != 0);
+    *fMD5             = ((RegVal & BIT_22) != 0);
+    *fWireless        = ((RegVal & BIT_21) != 0);
+    *fAES_XTS         = ((RegVal & BIT_20) != 0);
+    *ARC4             = (uint8_t)((RegVal >> 18) & MASK_2_BITS);
+    *fDESspeed        = ((RegVal & BIT_17) != 0);
+    *fDESfb           = ((RegVal & BIT_16) != 0);
+    *fDES             = ((RegVal & BIT_15) != 0);
+    *fAESspeed        = ((RegVal & BIT_14) != 0);
+    *fAESfb           = ((RegVal & BIT_13) != 0);
+    *fAES             = ((RegVal & BIT_12) != 0);
+}
+
+
+static inline void
+EIP96_TOKEN_CTRL_STAT_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP96_Write32(Device,
+                  EIP96_REG_TOKEN_CTRL_STAT(PEnr),
+                  EIP96_REG_TOKEN_CTRL_STAT_DEFAULT);
+}
+
+
+static inline void
+EIP96_TOKEN_CTRL_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint8_t * const ActiveTokenCount,
+        bool * const fTokenLocationAvailable,
+        bool * const fResultTokenAvailable,
+        bool * const fTokenReadActive,
+        bool * const fContextCacheActive,
+        bool * const fContextFetch,
+        bool * const fResultContext,
+        bool * const fProcessingHeld,
+        bool * const fBusy)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP96_Read32(Device, EIP96_REG_TOKEN_CTRL_STAT(PEnr));
+
+    *fBusy                   = ((RegVal & BIT_15) != 0);
+    *fProcessingHeld         = ((RegVal & BIT_14) != 0);
+    *fResultContext          = ((RegVal & BIT_7) != 0);
+    *fContextFetch           = ((RegVal & BIT_6) != 0);
+    *fContextCacheActive     = ((RegVal & BIT_5) != 0);
+    *fTokenReadActive        = ((RegVal & BIT_4) != 0);
+    *fResultTokenAvailable   = ((RegVal & BIT_3) != 0);
+    *fTokenLocationAvailable = ((RegVal & BIT_2) != 0);
+    *ActiveTokenCount        = (uint8_t)((RegVal) & MASK_2_BITS);
+}
+
+
+static inline void
+EIP96_TOKEN_CTRL_STAT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const bool fOptimalContextUpdate,
+        const bool fCTNoTokenWait,
+        const bool fAbsoluteARC4,
+        const bool fAllowReuseCached,
+        const bool fAllowPostponedReuse,
+        const bool fZeroLengthResult,
+        const bool fTimeoutCounterEnable,
+        const bool fExtendedErrorEnable)
+{
+    uint32_t RegVal = EIP96_REG_TOKEN_CTRL_STAT_DEFAULT;
+
+    if(fOptimalContextUpdate)
+        RegVal |= BIT_16;
+
+    if(fCTNoTokenWait)
+        RegVal |= BIT_17;
+
+    if(fAbsoluteARC4)
+        RegVal |= BIT_18;
+
+    if(fAllowReuseCached)
+        RegVal |= BIT_19;
+
+    if(fAllowPostponedReuse)
+        RegVal |= BIT_20;
+
+    if(fZeroLengthResult)
+        RegVal |= BIT_21;
+
+    if(fTimeoutCounterEnable)
+        RegVal |= BIT_22;
+
+    if(fExtendedErrorEnable)
+        RegVal |= BIT_30;
+
+    EIP96_Write32(Device, EIP96_REG_TOKEN_CTRL_STAT(PEnr), RegVal);
+}
+
+
+static inline void
+EIP96_TOKEN_CTRL2_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const bool fAdvFifoMode,
+        const bool fPrepOvsChkDis,
+        const bool fFetchOvsChkDis,
+        const bool fDonePulses)
+{
+    uint32_t RegVal = 0;
+
+    if (fAdvFifoMode)
+        RegVal |= BIT_0;
+
+    if (fPrepOvsChkDis)
+        RegVal |= BIT_1;
+
+    if (fFetchOvsChkDis)
+        RegVal |= BIT_2;
+
+    if (fDonePulses)
+        RegVal |= BIT_3;
+
+    EIP96_Write32(Device, EIP96_REG_TOKEN_CTRL2(PEnr), RegVal);
+}
+
+
+static inline void
+EIP96_CONTEXT_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint16_t * const Error,
+        uint8_t * const AvailableTokenCount,
+        bool * const fActiveContext,
+        bool * const fNextContext,
+        bool * const fResultContext,
+        bool * const fErrorRecovery)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP96_Read32(Device, EIP96_REG_CONTEXT_STAT(PEnr));
+
+    *fErrorRecovery          = ((RegVal & BIT_21) != 0);
+    *fResultContext          = ((RegVal & BIT_20) != 0);
+    *fNextContext            = ((RegVal & BIT_19) != 0);
+    *fActiveContext          = ((RegVal & BIT_18) != 0);
+    *AvailableTokenCount     = (uint16_t)((RegVal >> 16) & MASK_2_BITS);
+    *Error                   = (uint16_t)((RegVal)       & MASK_16_BITS);
+}
+
+
+static inline void
+EIP96_CONTEXT_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t ContextSize,
+        bool fAddressMode,
+        bool fControlMode)
+{
+    uint32_t RegVal = 0;
+
+    if (fAddressMode)
+        RegVal |= BIT_8;
+
+    if (fControlMode)
+        RegVal |= BIT_9;
+
+    RegVal |= ContextSize & MASK_8_BITS;
+
+    Device_Write32(Device,EIP96_REG_CONTEXT_CTRL(PEnr), RegVal);
+}
+
+
+static inline void
+EIP96_OUT_TRANS_CTRL_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        uint8_t * const AvailableWord32Count,
+        uint8_t * const MinTransferWordCount,
+        uint8_t * const MaxTransferWordCount,
+        uint8_t * const TransferSizeMask)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP96_Read32(Device, EIP96_REG_OUT_TRANS_CTRL_STAT(PEnr));
+
+    *TransferSizeMask      = (uint8_t)((RegVal >> 24) & MASK_8_BITS);
+    *MaxTransferWordCount  = (uint8_t)((RegVal >> 16) & MASK_8_BITS);
+    *MinTransferWordCount  = (uint8_t)((RegVal >> 8)  & MASK_8_BITS);
+    *AvailableWord32Count  = (uint8_t)((RegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP96_OUT_BUF_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint8_t HoldOutputData,
+        const bool fBlockUpdateAppend,
+        const bool fLenDeltaEnable)
+{
+    uint32_t RegVal = EIP96_REG_OUT_BUF_CTRL_DEFAULT;
+
+    if (fBlockUpdateAppend)
+        RegVal |= BIT_31;
+
+    if (fLenDeltaEnable)
+        RegVal |= BIT_30;
+
+    RegVal |= (uint32_t)((((uint32_t)HoldOutputData) & MASK_5_BITS) << 3);
+
+    EIP96_Write32(Device, EIP96_REG_OUT_BUF_CTRL(PEnr), RegVal);
+}
+
+static inline void
+EIP96_CTX_NUM32_THR_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Threshold)
+{
+    EIP96_Write32(Device,
+                  EIP96_REG_CTX_NUM32_THR(PEnr),
+                  Threshold);
+}
+
+static inline void
+EIP96_CTX_NUM64_THR_L_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Threshold_L)
+{
+    EIP96_Write32(Device,
+                  EIP96_REG_CTX_NUM64_THR_L(PEnr),
+                  Threshold_L);
+}
+
+static inline void
+EIP96_CTX_NUM64_THR_H_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Threshold_H)
+{
+    EIP96_Write32(Device,
+                  EIP96_REG_CTX_NUM64_THR_H(PEnr),
+                  Threshold_H);
+}
+
+static inline void
+EIP96_ECN_TABLE_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const unsigned int index,
+        const unsigned int ECN0,
+        const unsigned int CLE0,
+        const unsigned int ECN1,
+        const unsigned int CLE1,
+        const unsigned int ECN2,
+        const unsigned int CLE2,
+        const unsigned int ECN3,
+        const unsigned int CLE3)
+{
+    uint32_t RegVal = 0;
+
+    RegVal |= (ECN0 & MASK_2_BITS);
+    RegVal |= (CLE0 & MASK_5_BITS) << 2;
+    RegVal |= (ECN1 & MASK_2_BITS) << 8;
+    RegVal |= (CLE1 & MASK_5_BITS) << 10;
+    RegVal |= (ECN2 & MASK_2_BITS) << 16;
+    RegVal |= (CLE2 & MASK_5_BITS) << 18;
+    RegVal |= (ECN3 & MASK_2_BITS) << 24;
+    RegVal |= (CLE3 & MASK_5_BITS) << 26;
+
+    Device_Write32(Device,EIP96_REG_ECN_TABLE(PEnr, index), RegVal);
+}
+
+static inline void
+EIP96_PRNG_CTRL_DEFAULT_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    EIP96_Write32(Device,
+                  EIP96_REG_PRNG_CTRL(PEnr),
+                  EIP96_REG_PRNG_CTRL_DEFAULT);
+}
+
+
+static inline void
+EIP96_PRNG_CTRL_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const bool fEnable,
+        const bool fAutoMode)
+{
+    uint32_t RegVal = EIP96_REG_PRNG_CTRL_DEFAULT;
+
+    if(fEnable)
+        RegVal |= BIT_0;
+
+    if(fAutoMode)
+        RegVal |= BIT_1;
+
+    EIP96_Write32(Device, EIP96_REG_PRNG_CTRL(PEnr), RegVal);
+}
+
+
+static inline void
+EIP96_PRNG_STAT_RD(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        bool * const fBusy,
+        bool * const fResultReady)
+{
+    uint32_t RegVal;
+
+    RegVal = EIP96_Read32(Device, EIP96_REG_PRNG_STAT(PEnr));
+
+    *fResultReady  = ((RegVal & BIT_1) != 0);
+    *fBusy         = ((RegVal & BIT_0) != 0);
+}
+
+
+static inline void
+EIP96_PRNG_SEED_L_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t SeedLo)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_SEED_L(PEnr), SeedLo);
+}
+
+
+static inline void
+EIP96_PRNG_SEED_H_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t SeedHi)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_SEED_H(PEnr), SeedHi);
+}
+
+
+static inline void
+EIP96_PRNG_KEY_0_L_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Key0Lo)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_KEY_0_L(PEnr), Key0Lo);
+}
+
+
+static inline void
+EIP96_PRNG_KEY_0_H_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Key0Hi)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_KEY_0_H(PEnr), Key0Hi);
+}
+
+
+static inline void
+EIP96_PRNG_KEY_1_L_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Key1Lo)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_KEY_1_L(PEnr), Key1Lo);
+}
+
+
+static inline void
+EIP96_PRNG_KEY_1_H_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t Key1Hi)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_KEY_1_H(PEnr), Key1Hi);
+}
+
+
+static inline void
+EIP96_PRNG_LFSR_L_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t LFSRLo)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_LFSR_L(PEnr), LFSRLo);
+}
+
+
+static inline void
+EIP96_PRNG_LFSR_H_WR(
+        Device_Handle_t Device,
+        const unsigned int PEnr,
+        const uint32_t LFSRHi)
+{
+    EIP96_Write32(Device, EIP96_REG_PRNG_LFSR_H(PEnr), LFSRHi);
+}
+
+
+#endif /* EIP96_LEVEL0_H_ */
+
+
+/* end of file eip96_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_event.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_event.h
new file mode 100644
index 0000000..214b310
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_event.h
@@ -0,0 +1,519 @@
+/* eip97_global_event.h
+ *
+ * EIP-97 Global Control Driver Library API:
+ * Event Management use case
+ *
+ * Refer to the EIP-97 Driver Library User Guide for information about
+ * re-entrance and usage from concurrent execution contexts of this API
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_EVENT_H_
+#define EIP97_GLOBAL_EVENT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint16_t, bool
+
+// EIP-97 Global Control Driver Library Types API
+#include "eip97_global_types.h" // EIP97_* types
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-97 Debug statistics counters.
+typedef struct
+{
+    // Input packets for each interface.
+    uint64_t Ifc_Packets_In[16];
+    // Output packets for each interface.
+    uint64_t Ifc_Packets_Out[16];
+    // Total processed packets for each processing pipe.
+    uint64_t Pipe_Total_Packets[16];
+    // Total amount of data processed in each pipe.
+    uint64_t Pipe_Data_Count[16];
+    // Current number of packets in each pipe.
+    uint8_t Pipe_Current_Packets[16];
+    // Maximum number of packets in each pipe.
+    uint8_t Pipe_Max_Packets[16];
+} EIP97_Global_Debug_Statistics_t;
+
+
+// EIP-97 Data Fetch Engine (DFE) thread status,
+// 1 DFE thread corresponds to 1 Processing Engine (PE)
+typedef struct
+{
+    // Number of 32-bit words currently available from the assigned CD FIFO for
+    // this thread
+    uint16_t CDFifoWord32Count;
+
+    // This field contains the number of the CDR from which the thread is
+    // currently processing Command Descriptors. A value of all ones
+    // (reset value) means unassigned, in that case all other thread status
+    // information is invalid
+    uint8_t CDR_ID;
+
+    // Size of the current DMA operation for this thread, only valid
+    // if fAtDMABusy or fDataDMABusy are true
+    uint16_t DMASize;
+
+    // When true the thread is currently busy DMA-ing Additional Token data
+    // to the Processing Engine
+    bool fAtDMABusy;
+
+    // When true the thread is currently busy DMA-ing packet data to
+    // the Processing Engine
+    bool fDataDMABusy;
+
+    // FATAL ERROR when true requiring Global SW or HW Reset.
+    // True when a DMA error was detected, the thread is stopped as
+    // a result of this. A DFE thread error interrupt for thread n occurs
+    // simultaneously with the assertion of this bit.
+    // Further information may be extracted from the other thread status
+    // registers.
+    // Note: A DMA error is a Host bus Master interface read/write error and is
+    // qualified as a fatal error. The result is unknown and in the worst case
+    // it can cause a system hang-up. The only correct way to recover is
+    // to issue a complete system reset (HW Reset or Global SW Reset).
+    bool fDMAError;
+} EIP97_Global_DFE_Status_t;
+
+// EIP-97 Data Store Engine (DSE) thread status,
+// 1 DSE thread corresponds to 1 Processing Engine (PE)
+typedef struct
+{
+    // Number of 32-bit words currently available from the assigned RD FIFO for
+    // this thread
+    uint16_t RDFifoWord32Count;
+
+    // This field contains the number of the RDR from which the thread is
+    // currently processing Result Descriptors. A value of all ones
+    // (reset value) means unassigned, in that case all other thread status
+    // information is invalid
+    uint8_t RDR_ID;
+
+    // Size of the current DMA operation for this thread, only valid
+    // if fDataDMABusy is true
+    uint16_t DMASize;
+
+    // When true the thread is currently busy flushing any remaining packet data
+    // from the Processing Engine either because it did not fit into
+    // the reserved packet buffer or because a destination not allowed
+    // interrupt (DSE thread n Irq) was fired
+    bool fDataFlushBusy;
+
+    // When true the thread is currently busy DMA-ing packet data from the
+    // Processing Engine to Host memory.
+    bool fDataDMABusy;
+
+    // FATAL ERROR when true requiring Global SW or HW Reset.
+    // True when a DMA error was detected, the thread is stopped as
+    // a result of this. A DSE thread error interrupt for thread n occurs
+    // simultaneously with the assertion of this bit.
+    // Further information may be extracted from the other thread status
+    // registers.
+    // Note: A DMA error is a Host bus Master interface read/write error and is
+    // qualified as a fatal error. The result is unknown and in the worst case
+    // it can cause a system hang-up. The only correct way to recover is
+    // to issue a complete system reset (HW Reset or Global SW Reset).
+    bool fDMAError;
+} EIP97_Global_DSE_Status_t;
+
+// EIP-96 Token Status
+typedef struct
+{
+    // Number of tokens located in the EIP-96, result token not included
+    // (maximum is two)
+    uint8_t ActiveTokenCount;
+
+    // If true then a new token can be read by the EIP-96
+    bool fTokenLocationAvailable;
+
+    // If true then a (partial) result token is available in the EIP-96
+    bool fResultTokenAvailable;
+
+    // If true then a token is currently read by the EIP-96
+    bool fTokenReadActive;
+
+    // If true then the context cache contains a new context
+    bool fContextCacheActive;
+
+    // If true then the context cache is currently filled
+    bool fContextFetch;
+
+    // If true then the context cache contains result context data that
+    // needs to be updated
+    bool fResultContext;
+
+    // If true then no (part of) tokens are in the EIP-96 and no context
+    // update is required
+    bool fProcessingHeld;
+
+    // If true then packet engine is busy (a context is active)
+    bool fBusy;
+} EIP96_Token_Status_t;
+
+// EIP-96 Context Status
+typedef struct
+{
+    /*
+     * Packet processing error bit mask:
+        error_0  Packet length error
+        error_1  Token error, unknown token command/instruction.
+        error_2  Token contains to much bypass data.
+        error_3  Cryptographic block size error.
+        error_4  Hash block size error (basic hash only).
+        error_5  Invalid command/algorithm/mode/combination.
+        error_6  Prohibited algorithm.
+        error_7  Hash input overflow (basic hash only).
+        error_8  TTL / HOP-limit underflow.
+        error_9  Authentication failed.
+        error_10 Sequence number check failed / roll-over detected.
+        error_11 SPI check failed.
+        error_12 Checksum incorrect.
+        error_13 Pad verification failed.
+        error_14 Internal Packet Engine time-out:
+                 FATAL ERROR when set requiring Global SW or HW Reset.
+        error_15 Reserved error bit, will never be set to 1b.
+     */
+    uint16_t Error;
+
+    // Number of available tokens is the sum of new, active and result tokens
+    // that are available
+    uint8_t AvailableTokenCount;
+
+    // True indicates that a context is active
+    bool fActiveContext;
+
+    // True indicates that a new context is (currently) loaded
+    bool fNextContext;
+
+    // True indicates that a result context data needs to be stored.
+    // Result context and next context cannot be both active.
+    bool fResultContext;
+
+    // True indicates that an existing error condition has not yet been properly
+    // handled to completion. Note that the next packet context and data fetch
+    // can be started. In addition, error bits may still be active due
+    // to the previous packet.
+    bool fErrorRecovery;
+} EIP96_Context_Status_t;
+
+// EIP-96 Interrupt Status
+typedef struct
+{
+    // FATAL ERROR when true requiring Global SW or HW Reset.
+    // True when the input fetch engine does not properly receive all packet
+    // data.
+    bool fInputDMAError;
+
+    // True when the output store engine does not properly store all packet data
+    bool fOutputDMAError;
+
+    // A logic OR of the error_0 up to and including error_7 of the Error field
+    // in the EIP-96 Context Status
+    bool fPacketProcessingError;
+
+    // FATAL ERROR when true requiring Global SW or HW Reset.
+    // True when the Internal Packet Engine time-out, copy of error_14 from
+    // the Error field in the EIP-96 Context Status
+    // Fatal Error that requires the engine reset (via HW Reset or
+    // Global SW Reset)
+    bool fPacketTimeout;
+
+    // FATAL ERROR when true requiring Global SW or HW Reset.
+    // True when Fatal internal error within EIP-96 Packet Engine is detected,
+    // reset of engine required via HW Reset or Global SW Reset).
+    bool fFatalError;
+
+    // If true then there is at least one pending EIP-96 interrupt
+    bool fPeInterruptOut;
+
+    // If true then the input_dma_error interrupt is enabled
+    bool fInputDMAErrorEnabled;
+
+    // If true then the output_dma_error interrupt is enabled
+    bool fOutputDMAErrorEnabled;
+
+    // If true then the packet_processin interrupt is enabled
+    bool fPacketProcessingEnabled;
+
+    // If true then the packet_timeout interrupt is enabled
+    bool fPacketTimeoutEnabled;
+
+    // If true then the packet_timeout interrupt is enabled
+    bool fFatalErrorEnabled;
+
+    // If true then the EIP-96 interrupt output is enabled.
+    // If false then the EIP-96 interrupts will never become active.
+    bool fPeInterruptOutEnabled;
+} EIP96_Interrupt_Status_t;
+
+// EIP-96 Output Transfer Status
+typedef struct
+{
+    // Number of (32-bit) words that are available in the 2K Bytes data
+    // output buffer, shows value 255 when more than 255 words are available.
+    uint8_t AvailableWord32Count;
+
+    // Minimum number of words that is transferred per beat (fixed)
+    uint8_t MinTransferWordCount;
+
+    // Maximum number of words that can be transferred per beat (fixed)
+    uint8_t MaxTransferWordCount;
+
+    // Masks the number of available word entries to obtain an optimal
+    // transfer size (fixed)
+    uint8_t TransferSizeMask;
+} EIP96_Output_Transfer_Status_t;
+
+// EIP-96 PRNG Status
+typedef struct
+{
+    // True when the PRNG is busy generating a Pseudo-Random Number
+    bool fBusy;
+
+    // True when a valid Pseudo-Random Number is available
+    bool fResultReady;
+} EIP96_PRNG_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Debug_Statistics_Get
+ *
+ * This function returns debug statistics information in
+ * the EIP97_Global_Debug_Statistics_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Debug_Statistics_p (output)
+ *     Pointer to the data structure where the debug statistics
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_Debug_Statistics_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        EIP97_Global_Debug_Statistics_t * const Debug_Statistics_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DFE_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP97_Global_DFE_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the DFE status must be obtained.
+ *
+ * DFE_Status_p (output)
+ *     Pointer to the data structure where the DFE status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_DFE_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP97_Global_DFE_Status_t * const DFE_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DSE_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP97_Global_DSE_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the DSE status must be obtained.
+ *
+ * DSE_Status_p (output)
+ *     Pointer to the data structure where the DSE status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_DSE_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP97_Global_DSE_Status_t * const DSE_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Token_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP96_Token_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the status must be obtained.
+ *
+ * Token_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Token status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Token_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Token_Status_t * const Token_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Context_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP96_Context_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the status must be obtained.
+ *
+ * Context_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Context status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Context_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Context_Status_t * const Context_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_OutXfer_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP96_Output_Transfer_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the status must be obtained.
+ *
+ * OutXfer_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Output Transfer status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_OutXfer_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Output_Transfer_Status_t * const OutXfer_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_PRNG_Status_Get
+ *
+ * This function returns hardware status information in
+ * the EIP96_PRNG_Status_t data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE for which the status must be obtained.
+ *
+ * OutXfer_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 PRNG status
+ *     will be stored.
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_PRNG_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_PRNG_Status_t * const PRNG_Status_p);
+
+
+#endif /* EIP97_GLOBAL_EVENT_H_ */
+
+
+/* end of file eip97_global_event.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_fsm.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_fsm.h
new file mode 100644
index 0000000..143efed
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_fsm.h
@@ -0,0 +1,76 @@
+/* eip97_global_fsm.h
+ *
+ * EIP-97 Global Control Driver Library API State Machine Internal Interface
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_FSM_H_
+#define EIP97_GLOBAL_FSM_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "eip97_global_types.h"            // EIP97_Global_Error_t
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-97 Global Control Driver Library API States
+typedef enum
+{
+    EIP97_GLOBAL_STATE_UNKNOWN = 1,
+    EIP97_GLOBAL_STATE_SW_RESET_START,
+    EIP97_GLOBAL_STATE_SW_RESET_DONE,
+    EIP97_GLOBAL_STATE_HW_RESET_DONE,
+    EIP97_GLOBAL_STATE_INITIALIZED,
+    EIP97_GLOBAL_STATE_ENABLED,
+    EIP97_GLOBAL_STATE_FATAL_ERROR
+} EIP97_Global_State_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_State_Set
+ *
+ * This function check whether the transition from the "CurrentState" to the
+ * "NewState" is allowed and if yes changes the former to the latter.
+ *
+  * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : state transition is not allowed
+ */
+EIP97_Global_Error_t
+EIP97_Global_State_Set(
+        volatile EIP97_Global_State_t * const CurrentState,
+        const EIP97_Global_State_t NewState);
+
+
+#endif /* EIP97_GLOBAL_FSM_H_ */
+
+
+/* end of file eip97_global_fsm.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_init.h
new file mode 100644
index 0000000..4916e6b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_init.h
@@ -0,0 +1,498 @@
+/* eip97_global_init.h
+ *
+ * EIP-97 Global Control Driver Library API:
+ * Initialization, Un-initialization, Configuration use case
+ *
+ * Refer to the EIP-97 Driver Library User Guide for information about
+ * re-entrance and usage from concurrent execution contexts of this API
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_INIT_H_
+#define EIP97_GLOBAL_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Types API
+#include "eip97_global_types.h" // EIP97_* types
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Generic EIP HW version
+typedef struct
+{
+    // The basic EIP number.
+    uint8_t EipNumber;
+
+    // The complement of the basic EIP number.
+    uint8_t ComplmtEipNumber;
+
+    // Hardware Patch Level.
+    uint8_t HWPatchLevel;
+
+    // Minor Hardware revision.
+    uint8_t MinHWRevision;
+
+    // Major Hardware revision.
+    uint8_t MajHWRevision;
+} EIP_Version_t;
+
+// EIP-202 HW options
+typedef struct
+{
+    // Number of statically configured Descriptor Rings
+    uint8_t NofRings;
+
+    // Number of statically configured Processing Engines,
+    // value 0 indicates 8 PEs
+    uint8_t NofPes;
+
+    // If true then 64 bit descriptors will contain a particle
+    // size/fill level extension word to allow particle sizes larger
+    // than 1 MB.
+    bool fExpPlf;
+
+    // Command Descriptor FIFO size, the actual size is 2^CF_Size 32-bit
+    // words.
+    uint8_t CF_Size;
+
+    // Result Descriptor FIFO size, the actual size is 2^RF_Size 32-bit
+    // words.
+    uint8_t RF_Size;
+
+    // Host interface type:
+    // 0 = PLB, 1 = AHB, 2 = TCM, 3 = AXI
+    uint8_t HostIfc;
+
+    // Maximum supported DMA length is 2^(DMA_Len+1) – 1 bytes
+    uint8_t DMA_Len;
+
+    // Host interface data width:
+    // 0 = 32 bits, 1 = 64 bits, 2 = 128 bits, 3 = 256 bits
+    uint8_t HDW;
+
+    // Target access block alignment. If this value is larger than 0,
+    // the distance between 2 rings, 2 AICs and between the DFE and the DSE
+    // in the slave memory map is increased by a factor of 2^TgtAlign.
+    // This means that ring control registers start at 2^(TgtAlign+11) Byte
+    // boundaries (or a 2^(TgtAlign+12) Byte boundary for a combined
+    // CDR/RDR block), the DFE and DSE will start at a 2^(TgtAlign+10) Byte
+    // boundary and AICs will start at 2^(TgtAlign+8) Byte boundaries.
+    uint8_t TgtAlign;
+
+    // 64-bit addressing mode:
+    // false = 32-bit addressing,
+    // true = 64-bit addressing
+    bool fAddr64;
+} EIP202_Options_t;
+
+// EIP-202 HW options2
+typedef struct
+{
+    // Number of statically configured Look-aside interfaces
+    uint8_t NofLA_Ifs;
+
+    // Number of statically configured Inline interfaces
+    uint8_t NofIN_Ifs;
+
+    // AXI master interface only
+    // Number of write channels for a high-performance AXI master interface
+    // minus 1
+    uint8_t NofAXI_WrChs;
+
+    // AXI master interface only
+    // Number of read clusters for a high-performance AXI master interface.
+    uint8_t NofAXI_RdClusters;
+
+    // AXI master interface only
+    // Number of read channels per read cluster for a high-performance AXI
+    // master interface, minus 1
+    uint8_t NofAXI_RdCPC;
+
+} EIP202_Options2_t;
+
+// EIP-206 HW options
+typedef struct
+{
+    // These bits encode the EIP number for the EIP-96 Packet Engine.
+    // This field contains the value 96 (decimal) or 0x60.
+    uint8_t PE_Type;
+
+    // Input-side classifier configuration:
+    //    0 - no input classifier present
+    //    1 - EIP-207 input classifier present
+    uint8_t InClassifier;
+
+    // Output-side classifier configuration:
+    //    0 - no input classifier present
+    //    1 - EIP-207 output classifier present
+    uint8_t OutClassifier;
+
+    // Number of MAC [9:8] media interface RX/TX channels multiplexed and
+    // demultiplexed here, in range 0-8.
+    uint8_t NofMAC_Channels;
+
+    // Size of the Input Data Buffer in kilobytes.
+    uint8_t InDbufSizeKB;
+
+    // Size of the Input Token Buffer in kilobytes.
+    uint8_t InTbufSizeKB;
+
+    // Size of the Output Data Buffer in kilobytes.
+    uint8_t OutDbufSizeKB;
+
+    // Size of the Output Token Buffer in kilobytes.
+    uint8_t OutTbufSizeKB;
+
+} EIP206_Options_t;
+
+// EIP-96 HW options
+typedef struct
+{
+    // If true AES is available
+    bool fAES;
+
+    // If true AES-CFB-128 and AES-OFB-128 are available
+    bool fAESfb;
+
+    // If true fast AES core is integrated (12.8 bits/cycle).
+    // If false medium speed AES core is integrated (4.2 bits/cycle).
+    bool fAESspeed;
+
+    // If true DES and 3-DES are available
+    bool fDES;
+
+    // If true (3-)DES-CFB-64 and (3-)DES-OFB-64 are available.
+    bool fDESfb;
+
+    // If true fast (4-round) DES core is integrated.
+    // If false slow (3-round) DES core is integrated.
+    bool fDESspeed;
+
+    // ARC4 availability
+    // 0 - no ARC4 is available
+    // 1 - a slow speed ARC4 core is integrated (3.5 bits/cycle)
+    // 2 - a medium speed ARC4 core is integrated (6.4 bits/cycle)
+    // 3 - a high speed ARC4 core is integrated (8.0 bits/cycle)
+    uint8_t ARC4;
+
+    // If true AES-XTS is available
+    bool fAES_XTS;
+
+    // If true Wireless crypto algorithms (Kasumi, SNOW, ZUC) are available
+    bool fWireless;
+
+    // If true MD5 is available
+    bool fMD5;
+
+    // If true SHA-1 is available
+    bool fSHA1;
+
+    // If true fast SHA-1 core is integrated (12.8 bits/cycle)
+    // If false slow SHA-1 core is integrated (6.4 bits/cycle)
+    bool fSHA1speed;
+
+    // If true SHA-224/256 is available
+    bool fSHA224_256;
+
+    // If true SHA-384/512 is available
+    bool fSHA384_512;
+
+    // If true AES-XCBC-MAC is available.
+    // This also supports CBC-MAC and CMAC operations
+    bool fXCBC_MAC;
+
+    // If true fast AES-CBC-MAC core is integrated (12.8 bits/cycle)
+    // If false slow AES-CBC-MAC core is integrated (4.2 bits/cycle)
+    bool fCBC_MACspeed;
+
+    // If true AES-CBC-MAC core accepts all key lengths (128/192/256 bits)
+    // If false AES-CBC-MAC core accepts only keys with a length of 128 bits
+    bool fCBC_MACkeylens;
+
+    // If true GHASH core is available
+    bool fGHASH;
+
+} EIP96_Options_t;
+
+// EIP-97 HW options
+typedef struct
+{
+    // Number of statically configured Processing Engines
+    uint8_t NofPes;
+
+    // Size of statically configured Input Token Buffer
+    // The actual size is 2^in_tbuf_size in 32-bit words
+    uint8_t in_tbuf_size;
+
+    // Size of statically configured Input Data Buffer
+    // The actual size is 2^in_dbuf_size in 32-bit words
+    uint8_t in_dbuf_size;
+
+    // Size of statically configured Output Token Buffer
+    // The actual size is 2^in_tbuf_size in 32-bit words
+    uint8_t out_tbuf_size;
+
+    // Size of statically configured Output Data Buffer
+    // The actual size is 2^in_dbuf_size in 32-bit words
+    uint8_t out_dbuf_size;
+
+    // If true then the EIP(197) has a single central EIP-74 type DRBG.
+    // If false then each EIP-96 has its own local PRNG.
+    bool central_prng;
+
+    // If true then a Token Generator is available in EIP-97 HW
+    // If false the Host must supply the Token for the Processing Engine
+    bool tg;
+
+    // If true then a Transform Record Cache is available in EIP-97 HW
+    bool trc;
+} EIP97_Options_t;
+
+// Capabilities structure for EIP-97 HW
+typedef struct
+{
+    // HIA
+    EIP202_Options2_t   EIP202_Options2;
+    EIP202_Options_t    EIP202_Options;
+    EIP_Version_t       EIP202_Version;
+
+    // Processing Engine
+    EIP206_Options_t    EIP206_Options;
+    EIP_Version_t       EIP206_Version;
+
+    // Packet Engine
+    EIP96_Options_t     EIP96_Options;
+    EIP_Version_t       EIP96_Version;
+
+    // EIP-97 HW shell
+    EIP97_Options_t     EIP97_Options;
+    EIP_Version_t       EIP97_Version;
+
+} EIP97_Global_Capabilities_t;
+
+// Ring PE assignment map
+typedef struct
+{
+    // PE is selected via the index in the RingPE_Mask array,
+    // index i selects PE i
+    // Bit N:
+    //     0 - ring N is not assigned (cleared) to this PE
+    //     1 - ring N is assigned to this PE
+    uint32_t RingPE_Mask;
+
+    // PE is selected via the index in the RingPrio_Mask array,
+    // index i selects PE i
+    // Bit N:
+    //     0 - ring N is low priority
+    //     1 - ring N is high priority
+    uint32_t RingPrio_Mask;
+
+    // CDR Slots
+    // CDR0: bits 3-0,   CDR1: bits 7-4,   CDR2: bits 11-8,  CDR3: bits 15-12
+    // CDR4: bits 19-16, CDR5: bits 23-20, CDR6: bits 27-24, CDR7: bits 31-28
+    uint32_t RingSlots0;
+
+    // CDR Slots
+    // CDR8:  bits 3-0,   CDR9:  bits 7-4,   CDR10: bits 11-8, CDR11: bits 15-12
+    // CDR12: bits 19-16, CDR13: bits 23-20, CDR14: bits 27-24
+    uint32_t RingSlots1;
+
+} EIP97_Global_Ring_PE_Map_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Init
+ *
+ * This function performs the initialization of the EIP-97 Global Control HW
+ * interface and transits the API to the Initialized state.
+ *
+ * This function returns the EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR error code
+ * when it detects a mismatch in the Global Control Driver Library configuration
+ * and the use EIP-97 HW revision or configuration.
+ *
+ * Note: This function should be called either after the EIP-97 HW Reset or
+ *       after the Global SW Reset.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Device (input)
+ *     Handle for the Global Control device instance returned by Device_Find.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_Init(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset
+ *
+ * This function starts the Global SW Reset operation. If the reset operation
+ * can be done immediately this function returns EIP97_GLOBAL_NO_ERROR.
+ * Otherwise it will return EIP97_GLOBAL_BUSY_RETRY_LATER indicating
+ * that the reset operation has been started and is ongoing.
+ * The EIP97_Global_Reset_IsDone() function can be used to poll the device
+ * for the completion of the reset operation.
+ *
+ * Note: This function must be called before calling the EIP97_Global_Init()
+ *       function only if the EIP-97 HW Reset was not done. Otherwise it still
+ *       is can be called but it is not necessary.
+ *
+ * IOArea_p (output)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Device (input)
+ *     Handle for the Global Control device instance returned by Device_Find.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : Global SW Reset is done
+ *     EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ *     EIP97_GLOBAL_BUSY_RETRY_LATER: Global SW Reset is started but
+ *                                    not completed yet
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset_IsDone
+ *
+ * This function checks the status of the started by the EIP97_Global_Reset()
+ * function Global SW Reset operation for the EIP-97 device.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : Global SW Reset operation is done
+ *     EIP97_GLOBAL_BUSY_RETRY_LATER: Global SW Reset is started but
+ *                                    not completed yet
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset_IsDone(
+        EIP97_Global_IOArea_t * const IOArea_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_HWRevision_Get
+ *
+ * This function returns EIP-97, EIP202 HIA and EIP-96 PE hardware revision
+ * information in the Capabilities_p data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * Capabilities_p (output)
+ *     Pointer to the place holder in memory where the device capability
+ *     information will be stored.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ */
+EIP97_Global_Error_t
+EIP97_Global_HWRevision_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        EIP97_Global_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Configure
+ *
+ * This function performs the Ring to PE assignment and configures
+ * the Ring priority. The EIP-97 device supports multiple Ring interfaces
+ * as well as multiple PE's. One ring can be assigned to the same or different
+ * PE's. Multiple rings can be assigned to the same PE.
+ *
+ * This function transits the API from the Initialized to the Enabled state
+ * when the ring(s) assignment to the PE(s) is performed successfully.
+ *
+ * This function transits the API from the Enabled to the Initialized state
+ * when the ring(s) assignment to the PE(s) is cleared.
+ *
+ * This function keeps the API in the Enabled state when the ring(s) assignment
+ * to the PE(s) is changed but not cleared completely.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE that must be configured.
+ *
+ * RingPEMap_p (input)
+ *     Pointer to the data structure that contains the Ring PE assignment map.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_Configure(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        const EIP97_Global_Ring_PE_Map_t * const RingPEMap_p);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_SupportedFuncs_Get
+ *
+ * Return a bitmask of the supported functions (EIP96 options register).
+ */
+unsigned int
+EIP97_SupportedFuncs_Get(void);
+
+
+#endif /* EIP97_GLOBAL_INIT_H_ */
+
+
+/* end of file eip97_global_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_internal.h
new file mode 100644
index 0000000..1e5e388
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_internal.h
@@ -0,0 +1,115 @@
+/* eip97_global_internal.h
+ *
+ * EIP-97 Global Control Driver Library Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_INTERNAL_H_
+#define EIP97_GLOBAL_INTERNAL_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+// EIP-97 Driver Library Types API
+#include "eip97_global_types.h" // EIP97_* types
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define PE_DEFAULT_NR     0  // Default Processing Engine number
+
+#if (PE_DEFAULT_NR >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+#error "Error: PE_DEFAULT_NR must be less than EIP97_GLOBAL_MAX_NOF_PE_TO_USE"
+#endif
+
+// I/O Area, used internally
+typedef struct
+{
+    Device_Handle_t Device;
+    uint32_t State;
+} EIP97_True_IOArea_t;
+
+#define IOAREA(_p) ((volatile EIP97_True_IOArea_t *)_p)
+
+#ifdef EIP97_GLOBAL_STRICT_ARGS
+#define EIP97_GLOBAL_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+#define EIP97_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+#define EIP97_GLOBAL_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+#define EIP97_GLOBAL_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+#else
+/* EIP97_GLOBAL_STRICT_ARGS undefined */
+#define EIP97_GLOBAL_CHECK_POINTER(_p)
+#define EIP97_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP97_GLOBAL_CHECK_INT_ATLEAST(_i, _min)
+#define EIP97_GLOBAL_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP97_GLOBAL_STRICT_ARGS */
+
+#define TEST_SIZEOF(type, size) \
+    extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP97_True_IOArea_t, EIP97_GLOBAL_IOAREA_REQUIRED_SIZE);
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Interfaces_Get
+ */
+void
+EIP97_Interfaces_Get(
+    unsigned int * const NofPEs_p,
+    unsigned int * const NofRings_p,
+    unsigned int * const NofLA_p,
+    unsigned int * const NofIN_p);
+
+/*----------------------------------------------------------------------------
+ * EIP97_DFEDSE_Offset_Get
+ */
+unsigned int
+EIP97_DFEDSE_Offset_Get(void);
+
+#endif /* EIP97_GLOBAL_INTERNAL_H_ */
+
+
+/* end of file eip97_global_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_level0.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_level0.h
new file mode 100644
index 0000000..6396dd8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_level0.h
@@ -0,0 +1,282 @@
+/* eip97_global_level0.h
+ *
+ * EIP-97 Global Control Level0 Internal interface
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_LEVEL0_H_
+#define EIP97_GLOBAL_LEVEL0_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"     // EIP97_RC_BASE, EIP97_BASE
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"          // Read32, Write32
+
+#define EIP97_REG_MST_CTRL_DEFAULT      0x00000000
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Read/Write register constants
+
+// Byte offsets of the EIP-97 Engine registers
+
+// EIP-97 Engine EIP number (0x61) and complement (0x9E)
+#define EIP97_SIGNATURE    ((uint16_t)0x9E61)
+
+#define EIP97_REG_OFFS     4
+
+#define EIP97_REG_CS_DMA_CTRL2  ((EIP97_RC_BASE)+(0x01 * EIP97_REG_OFFS))
+
+#define EIP97_REG_MST_CTRL ((EIP97_BASE)+(0x00 * EIP97_REG_OFFS))
+#define EIP97_REG_OPTIONS  ((EIP97_BASE)+(0x01 * EIP97_REG_OFFS))
+#define EIP97_REG_VERSION  ((EIP97_BASE)+(0x02 * EIP97_REG_OFFS))
+
+#define EIP97_REG_CS_DMA_CTRL2_DEFAULT  0x00000000
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Read32
+ *
+ * This routine writes to a Register location in the EIP-97.
+ */
+static inline uint32_t
+EIP97_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset)
+{
+    return Device_Read32(Device, Offset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Write32
+ *
+ * This routine writes to a Register location in the EIP97.
+ */
+static inline void
+EIP97_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    Device_Write32(Device, Offset, Value);
+}
+
+
+static inline bool
+EIP97_REV_SIGNATURE_MATCH(
+        const uint32_t Rev)
+{
+    return (((uint16_t)Rev) == EIP97_SIGNATURE);
+}
+
+
+static inline void
+EIP97_EIP_REV_RD(
+        Device_Handle_t Device,
+        uint8_t * const EipNumber,
+        uint8_t * const ComplmtEipNumber,
+        uint8_t * const HWPatchLevel,
+        uint8_t * const MinHWRevision,
+        uint8_t * const MajHWRevision)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP97_Read32(Device, EIP97_REG_VERSION);
+
+    *MajHWRevision     = (uint8_t)((RevRegVal >> 24) & MASK_4_BITS);
+    *MinHWRevision     = (uint8_t)((RevRegVal >> 20) & MASK_4_BITS);
+    *HWPatchLevel      = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *ComplmtEipNumber  = (uint8_t)((RevRegVal >> 8)  & MASK_8_BITS);
+    *EipNumber         = (uint8_t)((RevRegVal)       & MASK_8_BITS);
+}
+
+
+static inline void
+EIP97_MST_CTRL_WR(
+        const Device_Handle_t Device,
+        const unsigned int PENr,
+        const uint8_t RdCache,
+        const uint8_t WrCache,
+        const uint8_t SwapMethod,
+        const uint8_t Protection,
+        const uint8_t CtxCacheAlign,
+        const bool fWriteCacheNoBuf)
+{
+    uint32_t RegVal = EIP97_REG_MST_CTRL_DEFAULT;
+
+    IDENTIFIER_NOT_USED(PENr);
+
+    RegVal |= (uint32_t)((((uint32_t)fWriteCacheNoBuf) & MASK_1_BIT) << 18);
+    RegVal |= (uint32_t)((((uint32_t)CtxCacheAlign) & MASK_2_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)Protection) & MASK_4_BITS) << 12);
+    RegVal |= (uint32_t)((((uint32_t)SwapMethod) & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)WrCache)    & MASK_4_BITS) << 4);
+    RegVal |= (uint32_t)((((uint32_t)RdCache)    & MASK_4_BITS));
+
+    EIP97_Write32(Device, EIP97_REG_MST_CTRL, RegVal);
+}
+
+
+static inline void
+EIP97_CS_DMA_CTRL2_WR(
+        const Device_Handle_t Device,
+        const uint8_t FLUE_Swap_Mask,
+        const uint8_t FRC_Swap_Mask,
+        const uint8_t TRC_Swap_Mask,
+        const uint8_t ARC4_Swap_Mask)
+{
+    uint32_t RegVal = EIP97_REG_CS_DMA_CTRL2_DEFAULT;
+
+    RegVal |= (uint32_t)((((uint32_t)FLUE_Swap_Mask) & MASK_4_BITS) << 24);
+    RegVal |= (uint32_t)((((uint32_t)ARC4_Swap_Mask) & MASK_4_BITS) << 16);
+    RegVal |= (uint32_t)((((uint32_t)TRC_Swap_Mask)  & MASK_4_BITS) << 8);
+    RegVal |= (uint32_t)((((uint32_t)FRC_Swap_Mask)  & MASK_4_BITS));
+
+    EIP97_Write32(Device, EIP97_REG_CS_DMA_CTRL2, RegVal);
+}
+
+
+// EIP-97 Global Control Level0 Internal API extensions
+#define EIP97_REG_DBG_BASE 0xffb00
+#define EIP97_REG_DBG_RING_IN_COUNT_LO(n)  (EIP97_REG_DBG_BASE + 0x00 + 16*(n))
+#define EIP97_REG_DBG_RING_IN_COUNT_HI(n)  (EIP97_REG_DBG_BASE + 0x04 + 16*(n))
+#define EIP97_REG_DBG_RING_OUT_COUNT_LO(n) (EIP97_REG_DBG_BASE + 0x08 + 16*(n))
+#define EIP97_REG_DBG_RING_OUT_COUNT_HI(n) (EIP97_REG_DBG_BASE + 0x0c + 16*(n))
+#define EIP97_REG_DBG_PIPE_COUNT(n)  (EIP97_REG_DBG_BASE + 0x100 + 16*(n))
+#define EIP97_REG_DBG_PIPE_STATE(n)  (EIP97_REG_DBG_BASE + 0x104 + 16*(n))
+#define EIP97_REG_DBG_PIPE_DCOUNT_LO(n)  (EIP97_REG_DBG_BASE + 0x108 + 16*(n))
+#define EIP97_REG_DBG_PIPE_DCOUNT_HI(n)  (EIP97_REG_DBG_BASE + 0x10c + 16*(n))
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static inline void
+EIP97_OPTIONS_RD(
+        Device_Handle_t Device,
+        uint8_t * const NofPes,
+        uint8_t * const InTbufSize,
+        uint8_t * const InDbufSize,
+        uint8_t * const OutTbufSize,
+        uint8_t * const OutDbufSize,
+        bool * const fCentralPRNG,
+        bool * const fTG,
+        bool * const fTRC)
+{
+    uint32_t RevRegVal;
+
+    RevRegVal = EIP97_Read32(Device, EIP97_REG_OPTIONS);
+
+    *fTRC         = ((RevRegVal & BIT_31) != 0);
+    *fTG          = ((RevRegVal & BIT_27) != 0);
+    *fCentralPRNG = ((RevRegVal & BIT_26) != 0);
+    *OutDbufSize  = (uint8_t)((RevRegVal >> 16) & MASK_4_BITS);
+    *OutTbufSize  = (uint8_t)((RevRegVal >> 13) & MASK_3_BITS) + 3;
+    *InDbufSize   = (uint8_t)((RevRegVal >> 9)  & MASK_4_BITS);
+    *InTbufSize   = (uint8_t)((RevRegVal >> 6)  & MASK_3_BITS) + 3;
+    *NofPes       = (uint8_t)((RevRegVal)       & MASK_5_BITS);
+}
+
+static inline void
+EIP97_DBG_RING_IN_COUNT_RD(
+        Device_Handle_t Device,
+        unsigned int PENr,
+        uint64_t * const Counter)
+{
+    uint32_t val_lo,val_hi;
+    val_lo = EIP97_Read32(Device, EIP97_REG_DBG_RING_IN_COUNT_LO(PENr));
+    val_hi = EIP97_Read32(Device, EIP97_REG_DBG_RING_IN_COUNT_HI(PENr));
+
+    *Counter = ((uint64_t)val_hi << 32) | ((uint64_t)val_lo);
+}
+
+static inline void
+EIP97_DBG_RING_OUT_COUNT_RD(
+        Device_Handle_t Device,
+        unsigned int PENr,
+        uint64_t * const Counter)
+{
+    uint32_t val_lo,val_hi;
+    val_lo = EIP97_Read32(Device, EIP97_REG_DBG_RING_OUT_COUNT_LO(PENr));
+    val_hi = EIP97_Read32(Device, EIP97_REG_DBG_RING_OUT_COUNT_HI(PENr));
+
+    *Counter = ((uint64_t)val_hi << 32) | ((uint64_t)val_lo);
+}
+
+
+static inline void
+EIP97_DBG_PIPE_COUNT_RD(
+        Device_Handle_t Device,
+        unsigned int PENr,
+        uint64_t * const TotalPackets,
+        uint8_t * const CurrentPackets,
+        uint8_t * const MaxPackets)
+{
+    uint32_t val_lo,val_hi;
+    val_lo = EIP97_Read32(Device, EIP97_REG_DBG_PIPE_COUNT(PENr));
+    val_hi = EIP97_Read32(Device, EIP97_REG_DBG_PIPE_STATE(PENr));
+
+    *TotalPackets = (((uint64_t)val_hi & MASK_16_BITS )<< 32) | ((uint64_t)val_lo);
+    *CurrentPackets = (val_hi >> 16) & MASK_8_BITS;
+    *MaxPackets = (val_hi >> 24) & MASK_8_BITS;
+}
+
+
+static inline void
+EIP97_DBG_PIPE_DCOUNT_RD(
+        Device_Handle_t Device,
+        unsigned int PENr,
+        uint64_t * const Counter)
+{
+    uint32_t val_lo,val_hi;
+    val_lo = EIP97_Read32(Device, EIP97_REG_DBG_PIPE_DCOUNT_LO(PENr));
+    val_hi = EIP97_Read32(Device, EIP97_REG_DBG_PIPE_DCOUNT_HI(PENr));
+
+    *Counter = ((uint64_t)val_hi << 32) | ((uint64_t)val_lo);
+}
+
+#endif /* EIP97_GLOBAL_LEVEL0_H_ */
+
+
+/* end of file eip97_global_level0.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_prng.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_prng.h
new file mode 100644
index 0000000..0b19159
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_prng.h
@@ -0,0 +1,112 @@
+/* eip97_global_prng.h
+ *
+ * EIP-97 Global Control Driver Library API:
+ * PRNG Re-Seed use case
+ *
+ * Refer to the EIP-97 Driver Library User Guide for information about
+ * re-entrance and usage from concurrent execution contexts of this API
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EIP97_GLOBAL_PRNG_H_
+#define EIP97_GLOBAL_PRNG_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t
+
+// EIP-97 Global Control Driver Library Types API
+#include "eip97_global_types.h" // EIP97_* types
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-96 PRNG Re-seed data
+typedef struct
+{
+    // Seed value low 32-bit word
+    uint32_t SeedLo;
+
+    // Seed value high 32-bit word
+    uint32_t SeedHi;
+
+    // Key register 0 value low 32-bit word
+    uint32_t Key0Lo;
+
+    // Key register 0 value high 32-bit word
+    uint32_t Key0Hi;
+
+    // Key register 1 value low 32-bit word
+    uint32_t Key1Lo;
+
+    // Key register 1 value high 32-bit word
+    uint32_t Key1Hi;
+
+    // Seed value low 32-bit word
+    uint32_t LFSRLo;
+
+    // Seed value high 32-bit word
+    uint32_t LFSRHi;
+} EIP96_PRNG_Reseed_t;
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_PRNG_Reseed
+ *
+ * This function returns hardware revision information in the Capabilities_p
+ * data structure.
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE that must be re-seed.
+ *
+ * ReseedData_p (input)
+ *     Pointer to the PRNG seed and key data.
+ *
+ * Return value
+ *     EIP97_GLOBAL_NO_ERROR : operation is completed
+ *     EIP97_GLOBAL_ARGUMENT_ERROR : Passed wrong argument
+ *     EIP97_GLOBAL_ILLEGAL_IN_STATE : invalid API state transition
+ */
+EIP97_Global_Error_t
+EIP97_Global_PRNG_Reseed(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        const EIP96_PRNG_Reseed_t * const ReseedData_p);
+
+
+#endif /* EIP97_GLOBAL_PRNG_H_ */
+
+
+/* end of file eip97_global_prng.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_types.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_types.h
new file mode 100644
index 0000000..49d1a84
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/eip197/eip97_global_types.h
@@ -0,0 +1,97 @@
+/* eip97_global_types.h
+ *
+ * EIP97 Global Control Driver Library Public Interface:
+ * Common Type Definitions
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+#ifndef INCLUDE_GUARD_EIP97_GLOBAL_TYPES_H
+#define INCLUDE_GUARD_EIP97_GLOBAL_TYPES_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP97_GLOBAL_IOAREA_REQUIRED_SIZE       (2 * sizeof(void*))
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Error_t
+ *
+ * Status (error) code type returned by these API functions
+ * See each function "Return value" for details.
+ *
+ * EIP97_GLOBAL_NO_ERROR : successful completion of the call.
+ * EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR : not supported by the device.
+ * EIP97_GLOBAL_ARGUMENT_ERROR :  invalid argument for a function parameter.
+ * EIP97_GLOBAL_BUSY_RETRY_LATER : Device is busy.
+ * EIP97_GLOBAL_ILLEGAL_IN_STATE : illegal state transition
+ */
+typedef enum
+{
+    EIP97_GLOBAL_NO_ERROR = 0,
+    EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR,
+    EIP97_GLOBAL_ARGUMENT_ERROR,
+    EIP97_GLOBAL_BUSY_RETRY_LATER,
+    EIP97_GLOBAL_ILLEGAL_IN_STATE
+} EIP97_Global_Error_t;
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Events_t
+ *
+ * Bit-mask for the events that can be generated by the EIP-97 HW modules:
+ * DFE, DSE, EIP-96 PE
+ */
+typedef enum
+{
+    // Fatal error events
+    EIP97_GLOBAL_DFE_DMA_ERROR_EVENT = BIT_0,
+    EIP97_GLOBAL_DSE_DMA_ERROR_EVENT = BIT_1,
+    EIP97_GLOBAL_PE_TIMEOUT_EVENT    = BIT_2
+} EIP97_Global_Events_t;
+
+// Bit-mask for the events defined by EIP97_Global_Events_t
+typedef uint32_t EIP97_Global_EventStatus_t;
+
+// place holder for device specific internal data
+typedef struct
+{
+    uint32_t placeholder[EIP97_GLOBAL_IOAREA_REQUIRED_SIZE];
+} EIP97_Global_IOArea_t;
+
+
+#endif /* INCLUDE_GUARD_EIP97_GLOBAL_TYPES_H */
+
+
+/* end of file eip97_global_types.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/c_iotoken.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/c_iotoken.h
new file mode 100644
index 0000000..43b4e05
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/c_iotoken.h
@@ -0,0 +1,77 @@
+/* c_iotoken.h
+ *
+ * Default configuration file
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_IOTOKEN_H_
+#define C_IOTOKEN_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Enable extended errors
+//#define IOTOKEN_EXTENDED_ERRORS_ENABLE
+
+// Enable strict argument checking (input parameters)
+
+//#define IOTOKEN_STRICT_ARGS
+
+// Number of 32-bit words passed from Input to Output Token
+// without modifications
+#ifndef IOTOKEN_BYPASS_WORD_COUNT
+#define IOTOKEN_BYPASS_WORD_COUNT        0
+#endif
+
+#ifndef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX LOG_SEVERITY_CRIT
+#endif
+
+
+// Enable PKt ID increment
+//#IOTOKEN_INCREMENT_PKTID
+
+#ifndef IOTOKEN_PADDING_DEFAULT_ON
+#define IOTOKEN_PADDING_DEFAULT_ON 0
+#endif
+
+// Header Align for inbound DTLS
+#ifndef IOTOKEN_DTLS_HDR_ALIGN
+#define IOTOKEN_DTLS_HDR_ALIGN 0
+#endif
+
+
+/* end of file c_iotoken.h */
+
+
+#endif /* C_IOTOKEN_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/cs_iotoken.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/cs_iotoken.h
new file mode 100644
index 0000000..a279ca3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/cs_iotoken.h
@@ -0,0 +1,58 @@
+/* cs_iotoken.h
+ *
+ * Top-level configuration file
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef CS_IOTOKEN_H_
+#define CS_IOTOKEN_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "cs_ddk197.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+// Enable extended errors
+#ifdef DDK_EIP197_EXTENDED_ERRORS_ENABLE
+#define IOTOKEN_EXTENDED_ERRORS_ENABLE
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Enable strict argument checking (input parameters)
+#define IOTOKEN_STRICT_ARGS
+
+#ifdef DDK_EIP197_FW_IOTOKEN_METADATA_ENABLE
+// Number of 32-bit words passed from Input to Output Token
+// without modifications
+#define IOTOKEN_BYPASS_WORD_COUNT        4
+#else
+#define IOTOKEN_BYPASS_WORD_COUNT        0
+#endif
+
+/* end of file cs_iotoken.h */
+
+
+#endif /* CS_IOTOKEN_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken.h
new file mode 100644
index 0000000..6534c78
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken.h
@@ -0,0 +1,510 @@
+/* iotoken.h
+ *
+ * IO Token API
+ *
+ * Standard interface for the EIP-96 Crypto Engine.
+ *
+ * This interface specifies features common to all implementations
+ * of the IOToken API and its extensions.
+ *
+ * All the functions in this API are re-entrant for different tokens.
+ * All the functions in this API can be used concurrently for different tokens.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef IOTOKEN_H_
+#define IOTOKEN_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // uint32_t
+#include "api_dmabuf.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Physical address
+typedef struct
+{
+    uint32_t Lo; // Low 32 bits of the 64-bit address
+    uint32_t Hi; // High 32 bits of the 64-bit address, set to 0 if not used
+} IOToken_PhysAddr_t;
+
+// Standard EIP-96 Input Token header word options
+typedef struct
+{
+    // true - Use Context (SA) buffer 64-bit addresses, otherwise 32-bit
+    bool f64bitSA;
+
+    // true - there have been already packets processed for this SA
+    bool fReuseSA;
+
+} IOToken_Options_t;
+
+// Standard EIP-96 Input Token descriptor
+typedef struct
+{
+    // Input packet length (in bytes)
+    unsigned int InPacket_ByteCount;
+
+    // Initialization value for the Token Header Word
+    unsigned int TknHdrWordInit;
+
+    IOToken_Options_t Options;
+
+    // Packet flow type
+    unsigned int Type;
+
+    // Application-specific identifier that will be passed to Output Token
+    unsigned int AppID;
+
+    // Context record (SA) physical address
+    IOToken_PhysAddr_t SA_PhysAddr;
+
+    // Length (in 32-bit words) of optional bypass data
+    unsigned int BypassData_WordCount;
+
+    // Input Token extension
+    // Optional pointer to the token descriptor extension.
+    // This must be a pointer to the data structure of type
+    // IOToken_Input_Dscr_Ext_t. Set to NULL if not used.
+    void * Ext_p;
+
+} IOToken_Input_Dscr_t;
+
+// Standard EIP-96 Output Token descriptor
+typedef struct
+{
+    // Output packet length (in bytes)
+    unsigned int OutPacket_ByteCount;
+
+    // EIP-96 and EIP-202 packet processing error codes
+    unsigned int ErrorCode;
+
+    // Bypass data length (in bytes)
+    unsigned int BypassData_ByteCount;
+
+    // true - Hash byte(s) is/are appended at the end of packet data
+    bool fHashAppended;
+
+    // If fHashAppended is true then Hash_ByteCount contains a number of
+    // appended bytes
+    unsigned int Hash_ByteCount;
+
+    // true - Generic Bytes are appended at the end of packet data
+    bool fBytesAppended;
+
+    // true - Checksum field is appended at the end of packet data
+    bool fChecksumAppended;
+
+    // true - Next Header field is appended at the end of packet data
+    bool fNextHeaderAppended;
+
+    // true - Length field is appended at the end of packet data
+    bool fLengthAppended;
+
+    // Application-specific identifier that will be passed to Output Token
+    unsigned int AppID;
+
+    // Next Header result value retrieved from the IPsec trailer
+    // Only for packets with IPsec padding
+    unsigned int NextHeader;
+
+    // Number of detected (and removed) padding bytes
+    // Only for Inbound processing PKCS#7, RTP, IPSec, TLS and SSL
+    unsigned int Pad_ByteCount;
+
+    // Output Token descriptor extension
+    // Optional pointer to the Output Token descriptor extension where
+    // the parsed data from the token will be stored.
+    // This must be a pointer to the data structure of type
+    // IOToken_Output_Dscr_Ext_t. Set to NULL if not used.
+    void * Ext_p;
+
+} IOToken_Output_Dscr_t;
+
+// Note: IOTOKEN_IN_WORD_COUNT and IOTOKEN_OUT_WORD_COUNT are
+//       implementation-specific parameters and hence must be defined by
+//       the implementation instead of this generic IOToken interface.
+//
+//       The IOToken_InWordCount_Get() and IOToken_OutWordCount_Get()
+//       functions can also be used to obtain these values.
+//
+//       These values are constant per implementation and do not change
+//       at run-time.
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_InWordCount_Get
+ *
+ * This function returns the size (in 32-bit words) of the Input Token.
+ *
+ * Return value
+ *     >0  : Input Token size (IOTOKEN_IN_WORD_COUNT)
+ *
+ */
+unsigned int
+IOToken_InWordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_OutWordCount_Get
+ *
+ * This function returns the size (in 32-bit words) of the Output Token.
+ *
+ * Return value
+ *     >0  : Output Token size (IOTOKEN_OUT_WORD_COUNT)
+ *
+ */
+unsigned int
+IOToken_OutWordCount_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Create
+ *
+ * This function creates an Input Token.
+ *
+ * Dscr_p (input)
+ *     Pointer to the Input Token descriptor.
+ *
+ * Data_p (output)
+ *     Pointer to the memory location where the Input Token data will be stored.
+ *     The size of this buffer must be IOTOKEN_IN_WORD_COUNT 32-bit words
+ *     at least.
+ *     Each word in this buffer will be written using values from Token_p,
+ *     not specified (reserved) fields will be set to 0.
+ *
+ * Return value
+ *     <0  : Error, token not created
+ *      0  : Reserved
+ *     >0  : Success, number of created 32-bit Input Token words
+ *
+ */
+int
+IOToken_Create(
+        const IOToken_Input_Dscr_t * const Dscr_p,
+        uint32_t * Data_p);
+
+/*----------------------------------------------------------------------------
+ * IOToken_TokenConvert
+ *
+ * This function converts a command descriptor for LIP/IIP/IDT/LAB flow
+ * to an equivalent command descriptor for a LAC flow, while generating
+ * the EIP96 processing token required for that LAC flow.
+ *
+ * Data_p (input, output)
+ *     Pointer to packet token data, will be updated.
+ *
+ * PacketHandle (input()
+ *     DMABuf Handle representing the packet. Can be a single buffer or
+ *     a gather list.
+ *
+ * TokenContext_p (input)
+ *     Pointer to the Token Context used by the Token Builder.
+ *
+ * TokenBuf_p (output)
+ *     Buffer where the EIP96 processing token instructions will be stored.
+ *
+ * Return value:
+ *    <0 : Error.
+ *     0 : No token created, but not required (original packet flow is LAC or
+ *         INV-TR)
+ *    >0 : Token successfully created, length of EIP96 processing token
+ *         instructions in word.
+ */
+int
+IOToken_TokenConvert(
+        uint32_t * const Data_p,
+        DMABuf_Handle_t PacketHandle,
+        void * const TokenContext_p,
+        uint32_t * const TokenBuf_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Fixup
+ *
+ * Fix-up the packet after processing. Some fields cannot be inserted into
+ * the packet by the hardware because the packet is longer than will fit
+ * in the internal buffers and the part of the packet where the fields should
+ * be inserted, is already streamed out. Those fields are appended to the
+ * packet instead. This function inserts the appended data back into the packet.
+ *
+ * Data_p (input, output)
+ *     Result token data.
+ *
+ * PacketHandle (input, output).
+ *     DMABuf Handle that represents the packet to fix up. Can be a scatter
+ *     list.
+ *
+ * Return value:
+ *    <0 : Error.
+ *     0 : No fixup performed (not required).
+ *    >0 : Fixup performed.
+ */
+int
+IOToken_Fixup(
+        uint32_t * const Data_p,
+        const DMABuf_Handle_t PacketHandle);
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAAddr_Update
+ *
+ * This function updates the SA physical address in
+ * an already existing Input Token.
+ *
+ * SA_PhysAddr_p (input)
+ *     Pointer to the SA physical address.
+ *
+ * InTokenData_p (output)
+ *     Pointer to the memory location where the Input Token data will be updated.
+ *     The size of this buffer must be IOTOKEN_IN_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Return value
+ *     <0  : Error, token not updated
+ *      0  : Reserved
+ *     >0  : Success, number of updated 32-bit token words
+ *
+ */
+int
+IOToken_SAAddr_Update(
+        const IOToken_PhysAddr_t * const SA_PhysAddr_p,
+        uint32_t * InTokenData_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAReuse_Update
+ *
+ * This function updates the SA reuse flag in
+ * an already existing Input Token.
+ *
+ * fReuseSA (input)
+ *     True - enable Context Reuse auto detect, otherwise disable.
+ *
+ * InTokenData_p (output)
+ *     Pointer to the memory location where the Input Token data will be updated.
+ *     The size of this buffer must be IOTOKEN_IN_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Return value
+ *     <0  : Error, token not updated
+ *      0  : Reserved
+ *     >0  : Success, number of updated 32-bit token words
+ *
+ */
+int
+IOToken_SAReuse_Update(
+        const bool fReuseSA,
+        uint32_t * InTokenData_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Set
+ *
+ * This function sets a mark in an already existing Input Token. This mark will
+ * be passed from the Input Token to the Output Token where its presence can
+ * be checked with the IOToken_Mark_Check() function.
+ *
+ * The function implementation determines which field in the Input Token can
+ * be used for this.
+ *
+ * InTokenData_p (output)
+ *     Pointer to the memory location where the Input Token data will be updated.
+ *     The size of this buffer must be IOTOKEN_IN_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Return value
+ *     <0  : Error, token not updated
+ *      0  : Reserved
+ *     >0  : Success, number of updated 32-bit token words
+ *
+ */
+int
+IOToken_Mark_Set(
+        uint32_t * InTokenData_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Offset_Get
+ *
+ * This function returns a word offset in the output token where the mark
+ * is stored.
+ *
+ * Return value
+ *     <0  : Error
+ *      0  : Reserved
+ *     >0  : Success, offset of the 32-bit word in the output token where
+ *           the mark is stored
+ *
+ */
+int
+IOToken_OutMarkOffset_Get(void);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Parse
+ *
+ * This function parses an Output Token.
+ *
+ * Data_p (input)
+ *     Pointer to the memory location where the Output Token data will be stored.
+ *     The size of this buffer must be IOTOKEN_OUT_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Dscr_p (output)
+ *     Pointer to the Output Token descriptor where the parsed data from
+ *     the token will be stored.
+ *     Fields in this descriptor will be written using values from Data_p.
+ *
+ * Return value
+ *     <0  : Error, token not created
+ *      0  : Reserved
+ *     >0  : Success, number of parsed 32-bit Output Token words
+ *
+ */
+int
+IOToken_Parse(
+        const uint32_t * Data_p,
+        IOToken_Output_Dscr_t * const Dscr_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Check
+ *
+ * This function checks if the mark set by the IOToken_Mark_Set() function
+ * in the Input Token is also present in the corresponding Output Token.
+ *
+ * OutTokenData_p (input)
+ *     Pointer to the memory location where the Output Token data is stored
+ *     where the mark must be checked.
+ *     The size of this buffer must be IOTOKEN_OUT_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Return value
+ *     <0  : Error, token not checked
+ *      0  : Mark found in Output Token
+ *     >0  : Mark not found in Output Token,
+ *           number of checked 32-bit token words
+ */
+int
+IOToken_Mark_Check(
+        uint32_t * OutTokenData_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_PacketLegth_Get
+ *
+ * This function reads the packet size (in bytes) from
+ * an already existing Output Token.
+ *
+ * Data_p (input)
+ *     Pointer to the memory location where the Output Token data is stored.
+ *     The size of this buffer must be IOTOKEN_OUT_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * Pkt_ByteCount_p (output)
+ *     Pointer to the memory location where in packet size will be stored.
+ *
+ * Return value
+ *     <0  : Error, packet size not read
+ *      0  : Reserved
+ *     >0  : Success, number of read 32-bit token words
+ *
+ */
+int
+IOToken_PacketLegth_Get(
+        const uint32_t * Data_p,
+        unsigned int * Pkt_ByteCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_BypassLegth_Get
+ *
+ * This function reads the bypass data length (in 32-bit words) from
+ * an already existing Output Token.
+ *
+ * Data_p (input)
+ *     Pointer to the memory location where the Output Token data is stored.
+ *     The size of this buffer must be IOTOKEN_OUT_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * BD_ByteCount_p (output)
+ *     Pointer to the memory location where in bypass data size will be stored.
+ *
+ * Return value
+ *     <0  : Error, packet size not read
+ *      0  : Reserved
+ *     >0  : Success, number of read 32-bit token words
+ *
+ */
+int
+IOToken_BypassLegth_Get(
+        const uint32_t * Data_p,
+        unsigned int * BD_ByteCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_ErrorCode_Get
+ *
+ * This function reads the packet processing error codes if any from
+ * an already existing Output Token.
+ *
+ * Data_p (input)
+ *     Pointer to the memory location where the Output Token data is stored.
+ *     The size of this buffer must be IOTOKEN_OUT_WORD_COUNT 32-bit words
+ *     at least.
+ *
+ * ErrorCode_p (output)
+ *     Pointer to the memory location where packet processing error code
+ *     will be stored.
+ *
+ * Return value
+ *     <0  : Error, packet processing error code not read
+ *      0  : Reserved
+ *     >0  : Success, number of read 32-bit token words
+ *
+ */
+int
+IOToken_ErrorCode_Get(
+        const uint32_t * Data_p,
+        unsigned int * ErrorCode_p);
+
+
+/* end of file iotoken.h */
+
+
+#endif /* IOTOKEN_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken_ext.h
new file mode 100644
index 0000000..a1796bc
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/iotoken/iotoken_ext.h
@@ -0,0 +1,263 @@
+/* iotoken_ext.h
+ *
+ * IOToken API for Extended Server with Input Classification Engine (ICE) only
+ *
+ * All the functions in this API are re-entrant for different tokens.
+ * All the functions in this API can be used concurrently for different tokens.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef IOTOKEN_EXT_H_
+#define IOTOKEN_EXT_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Length of the EIP-197 Server extended command token (in 32-bit words)
+// Note: Based on 64-bit Context (SA) address only!
+// Take the maximum possible value, including 4 optional bypass data words.
+#define IOTOKEN_IN_WORD_COUNT        (6 + 4)
+// The inline token may be larger.
+#define IOTOKEN_IN_WORD_COUNT_IL     (8 + 4)
+
+// Length of the EIP-197 Server extended result token (in 32-bit words)
+// Take the maximum possible value, including 4 optional bypass data words.
+#define IOTOKEN_OUT_WORD_COUNT       (8 + 4)
+// The inline token may be larger.
+#define IOTOKEN_OUT_WORD_COUNT_IL    (8 + 4)
+
+#define IOTOKEN_FLOW_TYPE            3 // Extended packet flow
+
+// DTLS content type
+typedef enum
+{
+    IOTOKEN_DTLS_CTYPE_CHANGE_CIPHER,
+    IOTOKEN_DTLS_CTYPE_ALERT,
+    IOTOKEN_DTLS_CTYPE_HANDSHAKE,
+    IOTOKEN_DTLS_CTYPE_APP_DATA
+} IOToken_DTLS_ContentType_t;
+
+// Input token header word extended options
+typedef struct
+{
+    // true - DTLS CAPWAP header is present in the input DTLS packet.
+    //        Used only for inbound (Direction = 1) and ignored for outbound
+    //        processing.
+    bool fCAPWAP;
+
+    // Direction for the packet flow. true - inbound, false - outbound
+    bool fInbound;
+
+    // DTLS content type
+    IOToken_DTLS_ContentType_t ContentType;
+
+} IOToken_Options_Ext_t;
+
+// Input Token descriptor extension
+typedef struct
+{
+    // ARC4 state record pre-fetch control
+    // true - ARC4 state pre-fetch is used, otherwise (false) not
+    bool fARC4Prefetch;
+
+    // Input token header extended options
+    IOToken_Options_Ext_t Options;
+
+    // Packet flow selection (see the EIP-197 firmware API specification)
+    unsigned int HW_Services;
+
+    // Offset to the end of the bypass data (start of packet data) or
+    // length (in bytes) of bypass data
+    unsigned int Offset_ByteCount;
+
+    // Next header to be inserted with pad data during the ESP Outbound
+    // encapsulation, otherwise zero
+    unsigned int NextHeader;
+
+    // Number of bytes for additional authentication data in combined
+    // encyrpt-authenticate operations.
+    unsigned int AAD_ByteCount;
+
+    // User defined field for flow lookup.
+    uint16_t UserDef;
+
+    // Strip padding after IP datagrams
+    bool fStripPadding;
+
+    // Allow padding after IP datagrams
+    bool fAllowPadding;
+
+    // Copy Flow Label
+    bool fFL;
+
+    // Verify IPv4 checksum
+    bool fIPv4Chksum;
+
+    // Verify L4 checksum;
+    bool fL4Chksum;
+
+    // Parse Ethernet header
+    bool fParseEther;
+
+    // Keep outer header fter inbound tunnel operation
+    bool fKeepOuter;
+
+    // Always encapsulate last destination header (IPv6 ESP outbound transport).
+    bool fEncLastDest;
+
+    // Set to specify inline interface.
+    bool fInline;
+
+    // Reduced mask size for inbound SA with 1024-bit mask.
+    unsigned int SequenceMaskBitCount;
+
+    // Bypass data which will be passed unmodified from Input Token
+    // to Output Token
+    // Buffer size must IOTOKEN_BYPASS_WORD_COUNT (32-bit words) at least
+    // If not used set to NULL (IOTOKEN_BYPASS_WORD_COUNT must be set to 0)
+    unsigned int * BypassData_p;
+
+} IOToken_Input_Dscr_Ext_t;
+
+// Output Token descriptor extension
+typedef struct
+{
+    // For tunnel ESP processing
+    // IPv4 Type of Service or IPv6 Traffic Class field from inner IP header
+    unsigned int TOS_TC;
+
+    // For tunnel ESP processing
+    // IPv4 DontFragment field from inner IP header
+    bool fDF;
+
+    // Classification errors (CLE), see firmware specification for details
+    unsigned int CfyErrors;
+
+    // Extended errors, see firmware specification for details.
+    unsigned int ExtErrors;
+
+    // Copy of the Offset_ByteCount from the Input Token
+    unsigned int Offset_ByteCount;
+
+    // Valid only when fLengthAppended is true and both fChecksumAppended and
+    // fNextHeaderAppended are false (see Output Token Descriptor)
+    // Delta between the result packet length and the length value that
+    // must be inserted in the IP header
+    unsigned int IPDelta_ByteCount;
+
+    // Context record (SA) physical address
+    IOToken_PhysAddr_t SA_PhysAddr;
+
+    // Application-specific reference for Network Packet Header processing
+    // Comes to the Engine via the Context (SA) Record
+    unsigned int NPH_Context;
+
+    // Offset within the IPv6 header needed to complete the header processing
+    unsigned int NextHeaderOffset;
+
+    // Bypass data which will be passed unmodified from Input Token
+    // to Output Token
+
+    // Input packet was IPv6
+    bool fInIPv6;
+
+    // Ethernet parsing performed
+    bool fFromEther;
+
+    // Output packet is IPv6
+    bool fOutIPv6;
+
+    // Inbound tunnel operation
+    bool fInbTunnel;
+
+
+    // Buffer size must IOTOKEN_BYPASS_WORD_COUNT (32-bit words) at least
+    // If not used set to NULL (IOTOKEN_BYPASS_WORD_COUNT must be set to 0)
+    unsigned int * BypassData_p;
+
+} IOToken_Output_Dscr_Ext_t;
+
+// Lookaside Crypto packet Flow
+#define IOTOKEN_CMD_PKT_LAC       0x04
+
+// Lookaside IPsec packet flow
+#define IOTOKEN_CMD_PKT_LIP       0x02
+
+// Inline IPsec packet flow
+#define IOTOKEN_CMD_PKT_IIP       0x02
+
+// Lookaside IPsec packet flow, custom classification
+#define IOTOKEN_CMD_PKT_LIP_CUST  0x03
+
+// Inline IPsec packet flow, custom classification
+#define IOTOKEN_CMD_PKT_IIP_CUST  0x03
+
+// Lookaside IPsec with Token Builder offload packet flow
+#define IOTOKEN_CMD_PKT_LAIP_TB   0x18
+
+// Lookaside Basic with Token Builder offload packet flow
+#define IOTOKEN_CMD_PKT_LAB_TB    0x20
+
+// Inline Basic with Token Builder offload packet flow
+#define IOTOKEN_CMD_PKT_IB_TB    0x20
+
+// Lookaside DTLS (including CAPWAP)
+#define IOTOKEN_CMD_PKT_LDT       0x28
+
+// Inline DTLS (including CAPWAP)
+#define IOTOKEN_CMD_PKT_IDT       0x28
+
+// Inline MACsec
+#define IOTOKEN_CMD_PKT_IMA       0x38
+
+// Invalidate Transform Record command
+#define IOTOKEN_CMD_INV_TR        0x06
+
+// Invalidate Flow Record command
+#define IOTOKEN_CMD_INV_FR        0x05
+
+// Bypass operation.
+#define IOTOKEN_CMD_BYPASS        0x08
+
+// Bit mask that enables the flow lookup. Otherwise the transform lookup is performed.
+#define IOTOKEN_CMD_FLOW_LOOKUP   0x80
+
+#define IOTOKEN_USE_HW_SERVICE
+#define IOTOKEN_USE_TRANSFORM_INVALIDATE
+
+
+/* end of file iotoken_ext.h */
+
+
+#endif /* IOTOKEN_EXT_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/c_list.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/c_list.h
new file mode 100644
index 0000000..006f064
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/c_list.h
@@ -0,0 +1,51 @@
+/* c_list.h
+ *
+ * Default configuration for the List module
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_LIST_H_
+#define C_LIST_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level configuration
+#include "cs_list.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum supported number of the list instances
+#ifndef LIST_MAX_NOF_INSTANCES
+#define LIST_MAX_NOF_INSTANCES      2
+#endif // LIST_MAX_NOF_INSTANCES
+
+// Strict argument checking
+//#define LIST_STRICT_ARGS
+
+
+#endif /* C_LIST_H_ */
+
+
+/* end of file c_list.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/list.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/list.h
new file mode 100644
index 0000000..58e1a86
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/list/list.h
@@ -0,0 +1,376 @@
+/* list.h
+ *
+ * The List API for manipulation of a list of elements.
+ *
+ * This API can be used to implement lists of variable size.
+ * The list elements must be allocated statically or dynamically by the API
+ * user.
+ *
+ * The list instances can be allocated statically or dynamically.
+ *
+ * Note: the support for static list instances will be deprecated
+ *       in future versions. Do not use it anymore!
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef LIST_H_
+#define LIST_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Dummy list ID to use with the List API
+#define LIST_DUMMY_LIST_ID          0
+
+#define LIST_INTERNAL_DATA_SIZE     2
+
+/*----------------------------------------------------------------------------
+ * List_Status_t
+ *
+ * Return values for all the API functions.
+ */
+typedef enum
+{
+    LIST_STATUS_OK,
+    LIST_ERROR_BAD_ARGUMENT,
+    LIST_ERROR_INTERNAL
+} List_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * List_Element_t
+ *
+ * The element data structure.
+ *
+ */
+typedef struct
+{
+    // Pointer to a data object associated with this element,
+    // can be filled in by the API user
+    void * DataObject_p;
+
+    // Data used internally by the API implementation only,
+    // may not be written by the API user
+    void * Internal[LIST_INTERNAL_DATA_SIZE];
+
+} List_Element_t;
+
+
+/*----------------------------------------------------------------------------
+ * List_Init
+ *
+ * Initializes a list instance. The list is empty when this function
+ * returns. The List_Add() function must be used to populate the list
+ * instance with the elements.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * This function must be called before any other function
+ * for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Handle_p was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_Init(
+        const unsigned int ListID,
+        void * const ListInstance_p);
+
+
+/*----------------------------------------------------------------------------
+ * List_Uninit
+ *
+ * Uninitializes the requested list instance. All the resources
+ * associated with this instance will be freed before this function returns.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * This function must be called in the end when the list instance is not needed
+ * anymore.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, instance is uninitialized.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_Uninit(
+        const unsigned int ListID,
+        void * const ListInstance_p);
+
+
+/*----------------------------------------------------------------------------
+ * List_AddToHead
+ *
+ * Adds an element to the list head. The element will be added to
+ * the list instance when this function returns LIST_STATUS_OK.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Element_p (input)
+ *     Pointer to the element to be added to the list instance. This element
+ *     may not be already present in the list. Cannot be NULL.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_AddToHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t * const Element_p);
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveFromTail
+ *
+ * Removes an element from the list tail. The element will be removed from
+ * the list instance when this function returns LIST_STATUS_OK.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Element_pp (output)
+ *     Pointer to the memory location where the element from the list
+ *     instance will be stored.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Element_pp was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_RemoveFromTail(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t ** const Element_pp);
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveAnywhere
+ *
+ * Removes requested element from the list. The element will be removed from
+ * the list instance when this function returns LIST_STATUS_OK.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Element_p (input/output)
+ *     Pointer to the memory location where the element to be removed from
+ *     the list instance is stored.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Element_pp was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_RemoveAnywhere(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t * const Element_p);
+
+
+/*----------------------------------------------------------------------------
+ * List_GetListElementCount
+ *
+ * Gets the number of elements added to the list.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Count_p (output)
+ *     Pointer to the memory location where the list element count
+ *     will be stored.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Count_p was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_GetListElementCount(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        unsigned int * const Count_p);
+
+
+/*----------------------------------------------------------------------------
+ * List_GetHead
+ *
+ * Gets the list head.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Element_pp (output)
+ *     Pointer to the memory location where the element from the list
+ *     instance will be stored.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Handle_p was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_GetHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        const List_Element_t ** const Element_pp);
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveFromHead
+ *
+ * Removes an element from the list head. The element will be removed from
+ * the list instance when this function returns LIST_STATUS_OK.
+ *
+ * ListID (input)
+ *     List instance identifier to be initialized.
+ *     Ignored if ListInstance_p is not NULL.
+ *
+ * ListInstance_p (input)
+ *     Pointer to the List instance to be initialized.
+ *     If the ListID is used then ListInstance_p can be set to NULL.
+ *
+ * Element_pp (output)
+ *     Pointer to the memory location where the element from the list
+ *     instance will be stored.
+ *
+ * This function is re-entrant for different list instances.
+ * This function is not re-entrant for the same list instance.
+ *
+ * Return Values
+ *     LIST_STATUS_OK: Success, Handle_p was written.
+ *     LIST_ERROR_BAD_ARGUMENT: Invalid input parameter.
+ */
+List_Status_t
+List_RemoveFromHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t ** const Element_pp);
+
+
+/*----------------------------------------------------------------------------
+ * List_GetNextElement
+ *
+ * Gets the next element for the provided one.
+ *
+ * Element_p (input)
+ *     Pointer to the element for which the next element must be obtained.
+ *     Cannot be NULL.
+ *
+ * This function is re-entrant.
+ *
+ * Return Values
+ *     Pointer to the next element or NULL if not found.
+ */
+static inline List_Element_t *
+List_GetNextElement(
+        const List_Element_t * const Element_p)
+{
+    // Get the next element from the list
+    return Element_p->Internal[1];
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * List_GetInstanceByteCount
+ *
+ * Gets the memory size of the list instance (in bytes) excluding the list
+ * elements memory size. This list memory size can be used to allocate a list
+ * instance and pass a pointer to it subsequently to the List_*() functions.
+ *
+ * This function is re-entrant and can be called any time.
+ *
+ * Return Values
+ *     Size of the list administration memory in bytes.
+ */
+unsigned int
+List_GetInstanceByteCount(void);
+
+
+#endif /* LIST_H_ */
+
+
+/* end of file list.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/c_ringhelper.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/c_ringhelper.h
new file mode 100644
index 0000000..0fc77d2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/c_ringhelper.h
@@ -0,0 +1,40 @@
+/* c_ringhelper.h
+ *
+ * Default configuration options for the Ring Helper.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#include "cs_ringhelper.h" // top-level product configuration options
+
+/*
+ * The following configuration parameters are available for the Ring Helper
+ */
+
+// when enabled, all function call parameters are sanity-checked
+// comment-out to disable this code
+//#define RINGHELPER_STRICT_ARGS
+
+// the following switch removes support for the Status Callback Function
+//#define RINGHELPER_REMOVE_STATUSFUNC
+
+// the following switch removes support for separate rings
+// use when only overlapping rings are used
+//#define RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+
+/* end of file c_ringhelper.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/ringhelper.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/ringhelper.h
new file mode 100644
index 0000000..c8696cd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/kit/ring/ringhelper.h
@@ -0,0 +1,422 @@
+/* ringhelper.h
+ *
+ * Ring Helper Library API specification.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_RINGHELPER_H
+#define INCLUDE_GUARD_RINGHELPER_H
+
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ * RingHelperCB_WriteFunc_t
+ *
+ * This routine must write a limited number of descriptors to the command ring
+ * and hand these off to the device for processing, using the mechanism
+ * supported by the device.
+ *
+ * If this is a command-only ring (not shared with resutls) AND the
+ * implementation of the callback interface is unable to provide the read
+ * position of the device in the command ring (see RingHelperCB_StatusFunc_t)
+ * then the Ring Helper module cannot know if the ring is almost full.
+ * Therefore, under these conditions, the implementation of this callback
+ * is also required to:
+ * - check that the descriptor position to be written is indeed free and does
+ *   not contain an unprocessed command descriptor (this happens when the ring
+ *   becomes full).
+ *
+ * This function can be called in response to invoking the RingHelper_Put API
+ * function and is expected to be fully re-entrant. If this is not possible,
+ * the caller must avoid the re-entrance of the RingHelper_Put API function.
+ *
+ * CallbackParam1_p
+ * CallbackParam2
+ *     These parameters are anonymous for the Ring Helper and were provided by
+ *     the caller during the ring initialization. They have meaning for the
+ *     the module that is invoked by this callback.
+ *
+ * WriteIndex
+ *     Zero-based index number in the command ring from where the descriptors
+ *     must be written. The caller guarantees that the descriptors can be
+ *     written sequentially and no index number wrapping will be required.
+ *     The implementation is expected to know the address of the command ring
+ *     and size of a descriptor.
+ *
+ * WriteCount
+ *     The number of descriptors to immediately add to the command ring.
+ *
+ * AvailableSpace
+ *     The currently available number of free positions in the command ring
+ *     to where the descriptors can be written.
+ *     The following always holds:
+ *
+ *     WriteCount <= AvailableSpace
+ *
+ *
+ * Descriptors_p
+ *     Pointer to the memory where the descriptors are currently stored.
+ *     The descriptors are available sequentially and back-to-back.
+ *
+ * DescriptorCount
+ *     The total number of descriptors that were requested to be added
+ *     to the command ring by the caller of the RingHelper_Put function.
+ *     When a write operation is split in two (due to index number wrapping),
+ *     this parameter is greater than WriteCount. Also if there is not enough
+ *     space available in the ring, this paramater is greater than WriteCount.
+ *     So the following holds:
+ *
+ *     DescriptorCount == WriteCount, if no index number wrapping occured
+ *                        in the caller's decision before calling this routine,
+ *                        and there is enough space in the ring;
+ *     DescriptorCount > WriteCount, if an index number wrapping occured
+ *                       in the caller's decision before calling this routine
+ *                       or there is not enough space in the ring;
+ *
+ * DescriptorSkipCount
+ *     The number of descriptors from Descriptors_p already copied. These
+ *     descriptors must be skipped. This parameter is required because the Ring
+ *     Helper does not know the size of a descriptor.
+ *     When an operation is split in two (due to index number wrapping),
+ *     the first call has this parameter set to zero,
+ *     and the second has it set to the number of descriptors written
+ *     by the first call.
+ *
+ * Return Value
+ *     <0  Failure code, this can be a Driver Library specific error code.
+ *      0  No descriptors could be written, but no explicit error
+ *     >0  Actual number of descriptors written
+ *
+ * It should be noted that returning a failure code will cause synchronization
+ * with the device to be lost and probably requires a reset of the device to
+ * recover.
+ */
+typedef int (* RingHelperCB_WriteFunc_t)(
+                    void * const CallbackParam1_p,
+                    const int CallbackParam2,
+                    const unsigned int WriteIndex,
+                    const unsigned int WriteCount,
+                    const unsigned int AvailableSpace,
+                    const void * Descriptors_p,
+                    const int DescriptorCount,
+                    const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelperCB_ReadFunc_t
+ *
+ * This routine is expected to read a limited number of descriptors from the
+ * result ring and then mark these positions as free, allowing new result
+ * descriptors (separate rings) or command descriptors (shared ring) to be
+ * written to these position. The exact method used depends on the device
+ * implementation.
+ *
+ * This function can be called in response to invoking the RingHelper_Get API
+ * function and is expected to be fully re-entrant. If this is not possible,
+ * the caller must avoid the re-entrance of the RingHelper_Get API function.
+ *
+ * CallbackParam1_p
+ * CallbackParam2
+ *     These parameters are anonymous for the Ring Helper and were provided by
+ *     the caller during the ring initialization. They have meaning for the
+ *     the module that is invoked by this callback.
+ *
+ * ReadLimit
+ *     The maximum number of descriptors that fit in Descriptors_p.
+ *     Also the maximum number of descriptors that can be read sequentially
+ *     without having to wrap the ReadIndex.
+ *     Also the maximum number of descriptors that are ready, if this was
+ *     indicated by the ReadyCount parameter in the call to RingHelper_Get.
+ *
+ * ReadIndex
+ *     Zero-based position in the result ring where the first descriptor can be
+ *     read. The caller guarantees that up to ReadLimit descriptors can be read
+ *     sequentially from this position without having to wrap the ReadIndex.
+ *     The implementation is expected to know the address of the command ring
+ *     and size of a descriptor.
+ *
+ * Descriptors_p
+ *     Pointer to the block of memory where up to ReadLimit whole descriptors
+ *     can be written back-to-back by the implementation.
+ *
+ * DescriptorSkipCount
+ *     The number of descriptors already stored from Descriptors_p. This memory
+ *     must be skipped. This parameter is required because the Ring Helper does
+ *     not know the size of a descriptor.
+ *     When an operation is split in two, the first call has this parameter set
+ *     to zero, and the second has it set to the number of descriptors returned
+ *     by the first call.
+ *
+ * Return Value
+ *    <0  Failure code, this can be a Driver Library specific error code.
+ *     0  No ready descriptors were available in the result ring.
+ *    >0  Actual number of descriptors copied from the result ring to the
+ *        buffer pointed to by Descriptors_p.
+ *
+ * It should be noted that returning a failure code will cause synchronization
+ * with the device to be lost and probably requires a reset of the device to
+ * recover.
+ */
+typedef int (* RingHelperCB_ReadFunc_t)(
+                    void * const CallbackParam1_p,
+                    const int CallbackParam2,
+                    const unsigned int ReadIndex,
+                    const unsigned int ReadLimit,
+                    void * Descriptors_p,
+                    const unsigned int DescriptorSkipCount);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelperCB_StatusFunc_t
+ *
+ * This routine reads and return the ring status from the device.
+ *
+ * This function can be called in response to invoking the RingHelper_Put API
+ * function and is expected to be fully re-entrant. If this is not possible,
+ * the caller must avoid the re-entrance of the RingHelper_Put API function.
+ *
+ * CallbackParam1_p
+ * CallbackParam2
+ *     These parameters are anonymous for the Ring Helper and were provided by
+ *     the caller during the ring initialization. They have meaning for the
+ *     the module that is invoked by this callback.
+ *
+ * DeviceReadPos_p
+ *     Pointer to the output parameter that will receive the most recent read
+ *     position used by the device. The value is the zero-based descriptor
+ *     index in the command ring. The caller will assume that the device has
+ *     not yet processed this descriptor.
+ *     The value -1 must be returned when the device cannot provide this info.
+ *     The implementation is expected to consistently return this value and
+ *     not to return -1 selectively. When the function has returned -1 once,
+ *     it is assumed not to support this functionality and will not be called
+ *     anew thereafter.
+ *
+ * Return Value
+ *    <0  Failure code, this can be a Driver Library specific error code.
+ *     0  Success  (also to be used when *DeviceReadPos_p was set to -1)
+ *
+ * It should be noted that returning a failure code will cause synchronization
+ * with the device to be lost and probably requires a reset of the device to
+ * recover.
+ */
+typedef int (* RingHelperCB_StatusFunc_t)(
+                    void * const CallbackParam1_p,
+                    const int CallbackParam2,
+                    int * const DeviceReadPos_p);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_CallbackInterface_t
+ *
+ * Data structure containing pointers to callback functions that will be used
+ * by the Ring Helper Library to manipulate descriptors in the ring.
+ */
+typedef struct
+{
+    // pointers to the functions that form the Callback Interface
+    // see type definitions above for details
+
+    // note: all three API functions are mandatory to provide
+    RingHelperCB_WriteFunc_t  WriteFunc_p;
+    RingHelperCB_ReadFunc_t   ReadFunc_p;
+    RingHelperCB_StatusFunc_t StatusFunc_p;
+
+    // the following two parameters will be used as parameters when invoking
+    // the above callback functions. The example usage is shown below.
+    void * CallbackParam1_p;        // typically I/O Area pointer
+    int CallbackParam2;             // typically Ring Number
+
+} RingHelper_CallbackInterface_t;
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_t
+ *
+ * Data structure used to hold the ring administration data. The caller must
+ * maintain an instance of this data structure for each ring.
+ *
+ * The caller should not access this data structure directly.
+ *
+ * For currency analysis, the following details have been specified:
+ * - RingHelper_Init writes all fields.
+ * - RingHelper_Put and RingHelper_Get do NOT write shared fields and can
+ *   therefore be used concurrently.
+ * - RingHelper_Get and RingHelper_Notify are multiple exlusive use by design.
+ */
+typedef struct
+{
+    unsigned int IN_Size;
+    unsigned int IN_Tail;               // written by Put
+
+    unsigned int OUT_Size;
+    unsigned int OUT_Head;              // written by Get
+
+    bool fSeparate;
+    bool fSupportsDeviceReadPos;        // written by Put
+
+    // callback interface
+    RingHelper_CallbackInterface_t CB;
+
+} RingHelper_t;
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Init
+ *
+ * This routine must be called once to initialize a ring.
+ *
+ * The Ring Helper module will start to use the ring(s) from index zero. The
+ * caller must make sure the device is configured accordingly.
+ *
+ * Ring_p
+ *     Pointer to the ring administration data.
+ *
+ * CallbackIF_p
+ *     References to the callback functions and parameters that will be used
+ *     by the Ring Helper to request manipulation of the descriptors.
+ *     The entire structure pointed to by this parameters will be copied.
+ *
+ * fSeparateRings
+ *     This parameter indicates whether the command and result rings share one
+ *     ring (one block of memory) or use separate rings (two memory blocks).
+ *
+ * MaxDescriptors_CommandRing
+ * MaxDescriptors_ResultRing
+ *     The maximum number of descriptors that fit in each of the rings.
+ *     The MaxDescriptors_ResultRing is ignored when fSeparateRings is false.
+ *
+ * Return value
+ *    <0  Failure code
+ *     0  Success
+ *
+ * None of the other API functions may be called for this Ring_p before this
+ * function returns with a success return value.
+ */
+int
+RingHelper_Init(
+        volatile RingHelper_t * const Ring_p,
+        volatile const RingHelper_CallbackInterface_t * const CallbackIF_p,
+        const bool fSeparateRings,
+        const unsigned int MaxDescriptors_CommandRing,
+        const unsigned int MaxDescriptors_ResultRing);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Put
+ *
+ * This routine can be used to add one or more descriptors to a specific
+ * command ring.
+ *
+ * Ring_p
+ *     Pointer to the ring administration data.
+ *
+ * Descriptors_p
+ *     Pointer to where to read the array of descriptors.
+ *
+ * DescriptorCount
+ *     Number of descriptors stored back-to-back in the array pointed to by
+ *     Descriptors_p.
+ *
+ * Return Value
+ *     <0  Failure code, this can be a Driver Library specific error code
+ *         returned from the RingHelperCB_WriteFunc_t callback function.
+ *     >0  Number of descriptors actually added to the command ring.
+ *      0  The command ring is full, no descriptors could be added
+ *         The caller should retry when the device has indicated that some
+ *         descriptors have been processed.
+ *
+ * This function is not re-entrant for the same Ring_p. It is allowed to call
+ * RingHelper_Get concurrently, even for the same Ring_p.
+ */
+int
+RingHelper_Put(
+        volatile RingHelper_t * const Ring_p,
+        const void * Descriptors_p,
+        const int DescriptorCount);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Get
+ *
+ * This routine can be used to read one or more descriptors from a specific
+ * result ring.
+ *
+ * Ring_p
+ *     Pointer to the ring administration data.
+ *
+ * ReadyCount
+ *     The number of descriptors the caller guarantees are available in the
+ *     result ring. This information is available from some devices.
+ *     Use -1 if this information is not availalble. In this case the
+ *     implementation of the read function (part of the callback interface)
+ *     must check this information when retrieving the descriptors.
+ *
+ * Descriptors_p
+ *     Pointer to the buffer where the descriptors will be written.
+ *
+ * DescriptorsLimit
+ *     The size of the buffer pointed to by Descriptors_p, expressed in the
+ *     maximum number of whole descriptors that fit into the buffer.
+ *     Or, if smaller than the buffer size, the maximum number of whole
+ *     descriptors that will be retrieved during this call.
+ *
+ * Return Value
+ *     <0 Failure code, this can be a Driver Library specific error code
+ *         returned from the RingHelperCB_ReadFunc_t callback function.
+ *      0 No descriptors ready to be retrieved, retry later
+ *     >0 Number of descriptors actually written from Descriptors_p
+ *
+ * This function is not re-entrant for the same Ring_p. It is allowed to call
+ * RingHelper_Put concurrently, even for the same Ring_p.
+ */
+int
+RingHelper_Get(
+        volatile RingHelper_t * const Ring_p,
+        const int ReadyCount,
+        void * Descriptors_p,
+        const int DescriptorsLimit);
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_FillLevel_Get
+ *
+ * This function returns a number of filled (used) descriptors in the ring
+ * specified.
+ *
+ * Ring_p
+ *     Pointer to the ring administration data.
+ *
+ * Return Value
+ *     <0 Failure code, this can be a Driver Library specific error code
+ *      0 No filled descriptors, empty ring
+ *     >0 Number of filled descriptors in the ring
+ *
+ * This function is not re-entrant for the same Ring_p. It is not allowed
+ * to call it concurrently with RingHelper_Put for the same Ring_p.
+ */
+int
+RingHelper_FillLevel_Get(
+        volatile RingHelper_t * const Ring_p);
+
+
+#endif /* Include Guard */
+
+
+/* end of file ringhelper.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/libc/clib.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/libc/clib.h
new file mode 100644
index 0000000..e0f47ae
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/libc/clib.h
@@ -0,0 +1,68 @@
+/* clib.h
+ *
+ * Driver Framework v4, C Library Abstraction
+ *
+ * This header function guarantees the availability of a select list of
+ * Standard C APIs. This makes the user of this API compiler independent.
+ * It also gives a single customization point for these functions.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CLIB_H
+#define INCLUDE_GUARD_CLIB_H
+
+/* guaranteed APIs:
+
+    memcpy
+    memmove
+    memset
+    memcmp
+    offsetof
+    strcmp
+
+*/
+
+/* Note: This is a template. Copy and customize according to your needs! */
+
+#if defined(linux) && defined(MODULE)
+
+#include <linux/string.h>     // memmove, memcpy, memset, strcmp
+#include <linux/stddef.h>     // offsetof
+
+#else
+
+#include <string.h>           // memmove, memset, strcmp, etc.
+#include <stddef.h>           // offsetof
+
+#endif
+
+
+/* Zero-init macro
+ *
+ *   _x (input)
+ *              Name of the variable that must be zeroed
+ *
+ */
+#define ZEROINIT(_x)  memset(&_x, 0, sizeof(_x))
+
+
+#endif /* Inclusion Guard */
+
+
+/* end of file clib.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log.h
new file mode 100644
index 0000000..899e10a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log.h
@@ -0,0 +1,252 @@
+/* log.h
+ *
+ * Logging API
+ *
+ * The service provided by this interface allows the caller to output trace
+ * messages. The implementation can use whatever output channel is available
+ * in a specific environment.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDEGUARD_LOG_H
+#define INCLUDEGUARD_LOG_H
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+// Logging API
+#include "log_impl.h"           // implementation specifics
+
+
+/*----------------------------------------------------------------------------
+ * LOG_SEVERITY_MAX
+ *
+ * This preprocessor symbol is used to control the definition of three macros
+ * that can be used to selectively compile three classes of log messages:
+ * Informational, Warnings and Critical. Define this symbol before including
+ * this header file. When absent, full logging is assumed.
+ */
+
+// set LOG_SEVERITY_MAX to one of the following values
+#define LOG_SEVERITY_NO_OUTPUT  0
+#define LOG_SEVERITY_CRIT       1
+#define LOG_SEVERITY_CRITICAL   1
+#define LOG_SEVERITY_WARN       2
+#define LOG_SEVERITY_WARNING    2
+#define LOG_SEVERITY_INFO       3
+
+#ifndef LOG_SEVERITY_MAX
+#ifdef _MSC_VER
+#pragma message("LOG_SEVERITY_MAX is undefined; assuming LOG_SEVERITY_INFO")
+#else
+#warning "LOG_SEVERITY_MAX is undefined; assuming LOG_SEVERITY_INFO"
+#endif
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_INFO
+#endif
+
+#if LOG_SEVERITY_MAX == LOG_SEVERITY_NO_OUTPUT
+    #define IDENTIFIER_NOT_USED_LOG_OFF(_x) IDENTIFIER_NOT_USED(_x)
+#else
+    #define IDENTIFIER_NOT_USED_LOG_OFF(_x)
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * LOG_CRIT_ENABLED
+ * LOG_WARN_ENABLED
+ * LOG_INFO_ENABLED
+ *
+ * This preprocessor symbols can be used to test if a specific class of log
+ * message has been enabled by the LOG_SEVERITY_MAX selection.
+ *
+ * Example usage:
+ *
+ * #ifdef LOG_SEVERITY_INFO
+ * // dump command descriptor details to log
+ * #endif
+ */
+
+#if LOG_SEVERITY_MAX >= LOG_SEVERITY_CRITICAL
+#define LOG_CRIT_ENABLED
+#endif
+
+#if LOG_SEVERITY_MAX >= LOG_SEVERITY_WARNING
+#define LOG_WARN_ENABLED
+#endif
+
+#if LOG_SEVERITY_MAX >= LOG_SEVERITY_INFO
+#define LOG_INFO_ENABLED
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Log_Message
+ *
+ * This function adds a simple constant message to the log buffer.
+ *
+ * Message_p
+ *     Pointer to the zero-terminated log message. The message must be
+ *     complete and terminated with a newline character ("\n"). This avoids
+ *     blending of partial messages.
+ *
+ * Return Value
+ *     None.
+ */
+#ifndef Log_Message
+void
+Log_Message(
+        const char * szMessage_p);
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump
+ *
+ * This function logs Hex Dump of a Buffer
+ *
+ * szPrefix
+ *     Prefix to be printed on every row.
+ *
+ * PrintOffset
+ *     Offset value that is printed at the start of every row. Can be used
+ *     when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ *     Pointer to the start of the array of bytes to hex dump.
+ *
+ * ByteCount
+ *     Number of bytes to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ *     None.
+ */
+#ifndef Log_HexDump
+void
+Log_HexDump(
+        const char * szPrefix_p,
+        const unsigned int PrintOffset,
+        const uint8_t * Buffer_p,
+        const unsigned int ByteCount);
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump32
+ *
+ * This function logs Hex Dump of an array of 32-bit words
+ *
+ * szPrefix
+ *     Prefix to be printed on every row.
+ *
+ * PrintOffset
+ *     Offset value that is printed at the start of every row. Can be used
+ *     when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ *     Pointer to the start of the array of 32-bit words to hex dump.
+ *
+ * Word32Count
+ *     Number of 32-bit words to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ *     None.
+ */
+#ifndef Log_HexDump32
+void
+Log_HexDump32(
+        const char * szPrefix_p,
+        const unsigned int PrintOffset,
+        const uint32_t * Buffer_p,
+        const unsigned int Word32Count);
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Log_FormattedMessage
+ *
+ * This function allows a message to be composed and output using a format
+ * specifier in line with printf. Caller should be restrictive in the format
+ * options used since not all platforms support all exotic variants.
+ *
+ * szFormat_p
+ *     Pointer to the zero-terminated format specifier string.
+ *
+ * ...
+ *     Variable number of additional arguments. These will be processed
+ *     according to the specifiers found in the format specifier string.
+ *
+ * Return Value
+ *     None.
+ */
+#ifndef Log_FormattedMessage
+void
+Log_FormattedMessage(
+        const char * szFormat_p,
+        ...);
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * LOG_CRIT
+ * LOG_WARN
+ * LOG_INFO
+ *
+ * These three helper macros can be used to conditionally compile code that
+ * outputs log messages and make the actual log line more compact.
+ * Each macro is enabled when the class of messages is activated with the
+ * LOG_SEVERITY_MAX setting.
+ *
+ * Example usage:
+ *
+ * LOG_INFO("MyFunc: selected mode %u (%s)\n", mode, Mode2Str[mode]);
+ *
+ * LOG_INFO(
+ *      "MyFunc: "
+ *      "selected mode %u (%s)\n",
+ *      mode,
+ *      Mode2Str[mode]);
+ *
+ * LOG_WARN("MyFunc: Unexpected return value %d\n", res);
+ */
+
+#undef LOG_CRIT
+
+#ifdef LOG_CRIT_ENABLED
+#define LOG_CRIT Log_FormattedMessageCRIT
+#else
+#define LOG_CRIT(...)
+#endif
+
+#undef LOG_WARN
+#ifdef LOG_WARN_ENABLED
+#define LOG_WARN Log_FormattedMessageWARN
+#else
+#define LOG_WARN(...)
+#endif
+
+#undef LOG_INFO
+#ifdef LOG_INFO_ENABLED
+#define LOG_INFO Log_FormattedMessageINFO
+#else
+#define LOG_INFO(...)
+#endif
+
+#endif /* Include Guard */
+
+/* end of file log.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log_impl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log_impl.h
new file mode 100644
index 0000000..7b6d787
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/log/log_impl.h
@@ -0,0 +1,38 @@
+/* log_impl.h
+ *
+ * Log Module, implementation for Linux Kernel Mode
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_LOG_IMPL_H
+#define INCLUDE_GUARD_LOG_IMPL_H
+
+#include <linux/kernel.h>   // printk
+
+#define Log_Message           printk
+#define Log_FormattedMessage  printk
+
+// backwards compatible implementation
+#define Log_FormattedMessageINFO  Log_FormattedMessage
+#define Log_FormattedMessageWARN  Log_FormattedMessage
+#define Log_FormattedMessageCRIT  Log_FormattedMessage
+
+#endif /* Include Guard */
+
+/* end of file log_impl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_cmd.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_cmd.h
new file mode 100644
index 0000000..603560b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_cmd.h
@@ -0,0 +1,58 @@
+/* shdevxs_cmd.h
+ *
+ * Opcodes (additional to those used by UMDevXS drive) for SHDevXS.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_CMD_H_
+#define SHDEVXS_CMD_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "umdevxs_cmd.h"
+
+
+enum {
+    UMDEVXS_OPCODE_SHDEVXS_GLOBAL_INIT = UMDEVXS_OPCODE_LAST,
+    UMDEVXS_OPCODE_SHDEVXS_GLOBAL_UNINIT,
+    UMDEVXS_OPCODE_SHDEVXS_TEST,
+    UMDEVXS_OPCODE_SHDEVXS_DMAPOOL_INIT,
+    UMDEVXS_OPCODE_SHDEVXS_DMAPOOL_UNINIT,
+    UMDEVXS_OPCODE_SHDEVXS_DMAPOOL_GETBASE,
+    UMDEVXS_OPCODE_SHDEVXS_RC_TRC_INVALIDATE,
+    UMDEVXS_OPCODE_SHDEVXS_RC_ARC4RC_INVALIDATE,
+    UMDEVXS_OPCODE_SHDEVXS_RC_LOCK,
+    UMDEVXS_OPCODE_SHDEVXS_RC_FREE,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_INIT,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_UNINIT,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_ENABLE,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_DISABLE,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_CLEAR,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_CLEARANDENABLE,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_SETHANDLER,
+    UMDEVXS_OPCODE_SHDEVXS_IRQ_WAIT,
+    UMDEVXS_OPCODE_SHDEVXS_PRNG_RESEED,
+    UMDEVXS_OPCODE_SHDEVXS_SUPPORTEDFUNCS_GET,
+};
+
+#endif /* SHDEVXS_CMD_H_ */
+
+/* shdevxs_cmd.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_dmapool.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_dmapool.h
new file mode 100644
index 0000000..9a004f4
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_dmapool.h
@@ -0,0 +1,138 @@
+/* shdevxs_dmapool.h
+ *
+ * Shared Device Access DMA pool API.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_DMAPOOL_H_
+#define SHDEVXS_DMAPOOL_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "shdevxs_dmapool.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Types Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    void * p;
+} SHDevXS_Addr_t;
+
+// DMA Pool data structure
+typedef struct
+{
+    // Host (virtual) address of the DMA pool memory bank
+    SHDevXS_Addr_t HostAddr;
+
+    // DMA (physical) address of the DMA pool memory bank
+    SHDevXS_Addr_t DMA_Addr;
+
+    // Size if bytes of the DMA pool memory bank
+    unsigned int ByteCount;
+
+    // Handle to be used for subset allocation.
+    int Handle;
+
+    // True when DMA buffer is cached, otherwise false
+    bool fCached;
+
+    // DMA pool identifier
+    unsigned int PoolId;
+
+} SHDevXS_DMAPool_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_DMAPool_Init
+ *
+ * This function initializes the DMA Pool for the calling application.
+ *
+ * API use order:
+ *     This function must be called once before any of the other functions.
+ *
+ * DMAPool_p (output)
+ *     Pointer to memory location where the DMA Pool control data will
+ *     be stored. Cannot be NULL.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_DMAPool_Init(
+        SHDevXS_DMAPool_t * const DMAPool_p);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_DMAPool_GetBase
+ *
+ * This function obtains the base address of the entire DMA pool area.
+ *
+ * BaseAddr_p (output)
+ *     Pointer to memory location where the DMA pool base address will
+ *     be stored.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_DMAPool_GetBase(
+        void ** BaseAddr_p);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_DMAPool_Uninit
+ *
+ * This function uninitializes and frees all the resources used by the calling
+ * application for the DMA pool.
+ *
+ * API use order:
+ *     This function must be called last, as clean-up step before stopping
+ *     the application.
+ *
+ * Return Value
+ *     None
+ */
+void
+SHDevXS_DMAPool_Uninit(void);
+
+
+#endif /* SHDEVXS_DMAPOOL_H_ */
+
+
+/* end of file shdevxs_dmapool.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_init.h
new file mode 100644
index 0000000..46f2391
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_init.h
@@ -0,0 +1,130 @@
+/* shdevxs_init.h
+ *
+ * Kernel suport Driver initialization API.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_INIT_H_
+#define SHDEVXS_INIT_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "shdevxs_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Types Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_Global_SetPrivileged
+ *
+ * This function is called once by the Global Control Driver to
+ * tell the kernel support driver that it has privileged access
+ * to the EIP hardware.
+ *
+ * API use order:
+ *     This function must be called first by the Global Control Driver, before
+ *     any other SHDevXS functions.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_Global_SetPrivileged(
+        void);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_Global_Init
+ *
+ * This function is called once by the Global Control Driver to
+ * tell the kernel support driver that it has done basic initialization
+ * of the hardware, so the Kernel Support Driver is now allowed to access
+ * hardware.
+ *
+ * API use order:
+ *     This function must be called once by the Global Control Driver, before
+ *     any other SHDevXS functions. It can be called again after
+ *     SHDevXS_HW_UnInit
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_Global_Init(
+        void);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_Global_UnInit
+ *
+ * This function is called once by the Global Control Driver when it
+ * exits. At that point, the Kernel Support Driver is no longer allowed to
+ * access hardware and no other applications may do so.
+ *
+ * API use order:
+ *     This function must be called once by the Global Control Driver, before
+ *     it exits.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_Global_UnInit(
+        void);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_Test
+ *
+ * Function to test whether communication with the kernel support driver
+ * is possible.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_Test(void);
+
+
+#endif /* SHDEVXS_INIT_H_ */
+
+
+/* end of file shdevxs_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_irq.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_irq.h
new file mode 100644
index 0000000..0d444c7
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_irq.h
@@ -0,0 +1,133 @@
+/* shdevxs_irq.h
+ *
+ * Shared Device Access Interrupts.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_IRQ_H_
+#define SHDEVXS_IRQ_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "shdevxs_irq.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Types Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+typedef void (*SHDevXS_InterruptHandler_t)(const int nIRQ,
+                                           const unsigned int flags);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_Init
+ *
+ * Initialize the IRQ handling subsystem. Must be called from the Global Control
+ * Driver once target accesses (along with endianness conversion) have been
+ * enabled.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_Init(void);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_UnInit
+ *
+ * Un-initialize the IRQ handling subsystem. Must be called from the
+ * Global Control Driver before shutting off any communication with the device.
+ *
+ */
+int
+SHDevXS_IRQ_UnInit(void);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_Enable
+ *
+ * Enable the specified IRQ on the hardware.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_Enable(const int nIRQ,
+                   const unsigned int Flags);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_Disable
+ *
+ * Disable the specified IRQ on the hardware.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_Disable(const int nIRQ,
+                    const unsigned int Flags);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_Clear
+ *
+ * Clear the specified IRQ on the hardware.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_Clear(const int nIRQ,
+                   const unsigned int Flags);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_Enable
+ *
+ * Clear and enable the specified IRQ on the hardware.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_ClearAndEnable(const int nIRQ,
+                           const unsigned int Flags);
+
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_IRQ_SetHandler
+ *
+ * Install the specified handler for the specified IRQ.
+ * If the handle is NULL, remove the handler from the interrupt.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_IRQ_SetHandler(
+        const int nIRQ,
+        SHDevXS_InterruptHandler_t HandlerFunction);
+
+
+#endif /* SHDEVXS_IRQ_H_ */
+
+
+/* end of file shdevxs_irq.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_prng.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_prng.h
new file mode 100644
index 0000000..0c8ed2a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_prng.h
@@ -0,0 +1,95 @@
+/* shdevxs_prng.h
+ *
+ * API to access EIP-96 Pseudo Random Number Generator.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_PRNG_H_
+#define SHDEVXS_PRNG_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "shdevxs_prng.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Types Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+// EIP-96 PRNG Re-seed data
+typedef struct
+{
+    // Seed value low 32-bit word
+    uint32_t SeedLo;
+
+    // Seed value high 32-bit word
+    uint32_t SeedHi;
+
+    // Key register 0 value low 32-bit word
+    uint32_t Key0Lo;
+
+    // Key register 0 value high 32-bit word
+    uint32_t Key0Hi;
+
+    // Key register 1 value low 32-bit word
+    uint32_t Key1Lo;
+
+    // Key register 1 value high 32-bit word
+    uint32_t Key1Hi;
+
+    // Seed value low 32-bit word
+    uint32_t LFSRLo;
+
+    // Seed value high 32-bit word
+    uint32_t LFSRHi;
+} SHDevXS_PRNG_Reseed_t;
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_PRNG_Ressed
+ *
+ * Reseed the internal PRNG of the EIP-96 to obtain predicatble IV's in
+ * known answer tests.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+SHDevXS_PRNG_Reseed(
+        SHDevXS_PRNG_Reseed_t * const Reseed_p);
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_SupportedFuncs_Get
+ *
+ * Return a bitmask of the functions supported by the device.
+ */
+unsigned int
+SHDevXS_SupportedFuncs_Get(void);
+
+#endif /* SHDEVXS_PRNG_H_ */
+
+
+/* end of file shdevxs_prng.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_rc.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_rc.h
new file mode 100644
index 0000000..78b07c1
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/shdevxs/shdevxs_rc.h
@@ -0,0 +1,120 @@
+/* shdevxs_rc.h
+ *
+ * Shared Device Access Record Cache API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef SHDEVXS_RC_H_
+#define SHDEVXS_RC_H_
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "shdevxs_rc.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Types Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_TRC_Record_Invalidate
+ *
+ * This function invalidates the transform record in the TRC.
+ *
+ * ByteOffset (input)
+ *     Record byte offset in the Transform Record Cache.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_TRC_Record_Invalidate(
+        const uint32_t ByteOffset);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_ARC4RC_Record_Invalidate
+ *
+ * This function invalidates the ARC4 state record in the ARC4RC.
+ *
+ * ByteOffset (input)
+ *     Record byte offset in the ARC4 Record Cache.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_ARC4RC_Record_Invalidate(
+        const uint32_t ByteOffset);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_RC_Lock
+ *
+ * This function locks the TRC for mutually exclusive use.
+ *
+ * Return Value
+ *     0  Success
+ *    0>  Failure, code is implementation-specific
+ */
+int
+SHDevXS_RC_Lock(void);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_RC_Free
+ *
+ * This function frees the TRC from the mutually exclusive use.
+ *
+ * Return Value
+ *     None
+ */
+void
+SHDevXS_RC_Free(void);
+
+
+/*----------------------------------------------------------------------------
+ * SHDevXS_RC_Record_Dummy_Addr_Get
+ *
+ * This function returns the dummy record address.
+ *
+ * Return Value
+ *     Record Cache record dummy (NULL) address.
+ */
+unsigned int
+SHDevXS_RC_Record_Dummy_Addr_Get(void);
+
+
+#endif /* SHDEVXS_RC_H_ */
+
+
+/* end of file shdevxs_rc.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_addrpair.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_addrpair.h
new file mode 100644
index 0000000..82486df
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_addrpair.h
@@ -0,0 +1,69 @@
+/* adapter_addrpair.h
+ *
+ * Convert an address (pointer) to a pair of 32-bit words.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_ADDDRPAIR_H_
+#define ADAPTER_ADDRPAIR_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h" // Type definitions uint32_t.
+
+/*----------------------------------------------------------------------------
+ * Adapter_AddrToWordPair
+ *
+ * Convert address (void *) to a pair of 32-bit words.
+ *
+ * Address_p (input)
+ *     The address to be converted.
+ * Offset (input)
+ *     Integer offset to be added to the address.
+ * WordLow_p (output)
+ *     Least significant address word.
+ * WordHigh_p (output)
+ *     Most significant address word.
+ */
+static inline void
+Adapter_AddrToWordPair(
+    const void *Address_p,
+    const int Offset,
+    uint32_t *WordLow_p,
+    uint32_t *WordHigh_p)
+{
+#ifdef ADAPTER_64BIT_HOST
+    uint64_t IntAddr;
+    IntAddr = (uint64_t)Address_p + Offset;
+    *WordLow_p = IntAddr & 0xFFFFFFFF;
+    *WordHigh_p = IntAddr >> 32;
+#else
+    *WordLow_p = (uint32_t)Address_p + Offset;
+    *WordHigh_p = 0;
+#endif
+}
+
+
+#endif /* ADAPTER_ADDRPAIR_H */
+
+
+/* end of file adapter_addrpair.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_dmabuf.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_dmabuf.h
new file mode 100644
index 0000000..56def4e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_dmabuf.h
@@ -0,0 +1,91 @@
+/* adapter_dmabuf.h
+ *
+ * Adapter DMABuf internal interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_DMABUF_H_
+#define ADAPTER_DMABUF_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"            // bool
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"          // DMAResource_Handle_t
+
+// DMABuf API
+#include "api_dmabuf.h"            // DMABuf_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define ADAPTER_DMABUF_ALIGNMENT_INVALID       -1
+
+
+/*----------------------------------------------------------------------------
+ * Function name
+ *
+ */
+
+DMAResource_Handle_t
+Adapter_DMABuf_Handle2DMAResourceHandle(
+        DMABuf_Handle_t Handle);
+
+
+DMABuf_Handle_t
+Adapter_DMAResource_Handle2DMABufHandle(
+        DMAResource_Handle_t Handle);
+
+
+void *
+Adapter_DMAResource_HostAddr(
+        DMAResource_Handle_t Handle);
+
+
+bool
+Adapter_DMAResource_IsSubRangeOf(
+        const DMAResource_Handle_t Handle1,
+        const DMAResource_Handle_t Handle2);
+
+
+bool
+Adapter_DMAResource_IsForeignAllocated(
+        DMAResource_Handle_t Handle);
+
+
+void
+Adapter_DMAResource_Alignment_Set(
+        const int Alignment);
+
+
+int
+Adapter_DMAResource_Alignment_Get(void);
+
+
+#endif /* ADAPTER_DMABUF_H_ */
+
+
+/* end of file adapter_dmabuf.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_firmware.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_firmware.h
new file mode 100644
index 0000000..b07a231
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_firmware.h
@@ -0,0 +1,101 @@
+/* adapter_firmware.h
+ *
+ * Interface for obtaining the firmware image.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_FIRMWARE_H
+#define INCLUDE_GUARD_ADAPTER_FIRMWARE_H
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// This data type represents a firmware resource.
+// use Adapter_Firmware_NULL to set to a known uninitialized value
+typedef void * Adapter_Firmware_t;
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_NULL
+ *
+ * This handle can be assigned to a variable of type Adapter_Firmware_t.
+ *
+ */
+extern const Adapter_Firmware_t Adapter_Firmware_NULL;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_Acquire
+ *
+ * Obtain access to a specific firmware image in the form of an array of 32-bit
+ * words. This function allocates any required buffers to store the
+ * firmware. Multiple calls to this function are possible and multiple
+ * firmware images remain valid at the same time. Access to the firmware
+ * image remains valid until Adapter_Firmware_Release is called.
+ *
+ * Firmware_Name_p (input)
+ *       Null terminated string that indicates which firmware to load.
+ *       This is typically a file name under a implementation-defined
+ *       fixed directory, but not all implementations are required to
+ *       load firmware from a file system.
+ *
+ * Firmware_p (output)
+ *       Pointer to array of 32-bit words that represents the loaded firmware.
+ *
+ * Firmware_Word32Count (output)
+ *       Size of the array in 32-bit words.
+ *
+ * Return: Adapter_Firmware_NULL if firmware failed to load.
+ *         any other value on success, can be passed to
+ *                          Adapter_Firmware_Release
+ */
+Adapter_Firmware_t
+Adapter_Firmware_Acquire(
+    const char * Firmware_Name_p,
+    const uint32_t ** Firmware_p,
+    unsigned int  * Firmware_Word32Count);
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_Release
+ *
+ * Release any resources that were allocated by a single call to
+ * Adapter_Firmware_Acquire. It is illegal to call this function multiple
+ * times for the same handle.
+ *
+ * FirmwareHandle (input)
+ *         Handle as returned by Adapter_Firmware_Acquire().
+ */
+void
+Adapter_Firmware_Release(
+   Adapter_Firmware_t FirmwareHandle);
+
+
+
+#endif /* Include Guard */
+
+/* end of file adapter_firmware.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_control_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_control_init.h
new file mode 100644
index 0000000..6ada10e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_control_init.h
@@ -0,0 +1,46 @@
+/* adapter_global_control_init.h
+ *
+ * Data types and Interfaces
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_INIT_H
+#define INCLUDE_GUARD_ADAPTER_INIT_H
+
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ *                           Adapter initialization
+ *----------------------------------------------------------------------------
+ */
+
+bool
+Adapter_Global_Control_Init(void);
+
+void
+Adapter_Global_Control_UnInit(void);
+
+void
+Adapter_Global_Control_Report_Build_Params(void);
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_global_control_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_cs_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_cs_init.h
new file mode 100644
index 0000000..4caf118
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_cs_init.h
@@ -0,0 +1,51 @@
+/* adapter_global_cs_init.h
+ *
+ * Global Classification Control Initialization interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_GLOBAL_CS_INIT_H
+#define INCLUDE_GUARD_ADAPTER_GLOBAL_CS_INIT_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ *                           Adapter initialization
+ *----------------------------------------------------------------------------
+ */
+
+bool
+Adapter_Global_Cs_Init(void);
+
+void
+Adapter_Global_Cs_UnInit(void);
+
+void
+Adapter_Global_Cs_Report_Build_Params(void);
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_global_cs_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_drbg_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_drbg_init.h
new file mode 100644
index 0000000..942741a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_drbg_init.h
@@ -0,0 +1,51 @@
+/* adapter_global_drbg_init.h
+ *
+ * Global DRBG Control Initialization interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_GLOBAL_DRBG_INIT_H_
+#define ADAPTER_GLOBAL_DRBG_INIT_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ *                           Adapter initialization
+ *----------------------------------------------------------------------------
+ */
+
+bool
+Adapter_Global_DRBG_Init(void);
+
+void
+Adapter_Global_DRBG_UnInit(void);
+
+void
+Adapter_Global_DRBG_StatusReport(void);
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_global_drbg_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_init.h
new file mode 100644
index 0000000..fb7ce04
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_init.h
@@ -0,0 +1,50 @@
+/* adapter_global_init.h
+ *
+ * Data types and Interfaces
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_GLOBAL_INIT_H
+#define INCLUDE_GUARD_ADAPTER_GLOBAL_INIT_H
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ *                           Adapter initialization
+ *----------------------------------------------------------------------------
+ */
+
+bool
+Adapter_Global_Init(void);
+
+void
+Adapter_Global_UnInit(void);
+
+void
+Adapter_Global_Report_Build_Params(void);
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_global_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_internal.h
new file mode 100644
index 0000000..c9c0039
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_global_internal.h
@@ -0,0 +1,41 @@
+/* adapter_global_internal.h
+ *
+ * Internal interface between parts of the Global Control adapter.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2014-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_GLOBAL_INTERNAL_H
+#define INCLUDE_GUARD_ADAPTER_GLOBAL_INTERNAL_H
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_global_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_init.h
new file mode 100644
index 0000000..c236258
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_init.h
@@ -0,0 +1,45 @@
+/* adapter_init.h
+ *
+ * Data types and Interfaces
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_INIT_H
+#define INCLUDE_GUARD_ADAPTER_INIT_H
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ *                           Adapter initialization
+ *----------------------------------------------------------------------------
+ */
+
+bool
+Adapter_Init(void);
+
+void
+Adapter_UnInit(void);
+
+void
+Adapter_Report_Build_Params(void);
+
+#endif /* Include Guard */
+
+/* end of file adapter_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts.h
new file mode 100644
index 0000000..00dd21a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts.h
@@ -0,0 +1,118 @@
+/* adapter_interrupts.h
+ *
+ * Adapter Interrupts interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_INTERRUPTS_H
+#define INCLUDE_GUARD_ADAPTER_INTERRUPTS_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"     // bool
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef void (* Adapter_InterruptHandler_t)(const int nIRQ, const unsigned int Flags);
+
+
+/*----------------------------------------------------------------------------
+ *                           Adapter_Interrupts
+ *----------------------------------------------------------------------------
+ */
+
+int
+Adapter_Interrupts_Init(
+        const int nIRQ);
+
+int
+Adapter_Interrupts_UnInit(
+        const int nIRQ);
+
+int
+Adapter_Interrupt_SetHandler(
+        const int nIRQ,
+        Adapter_InterruptHandler_t HandlerFunction);
+
+int
+Adapter_Interrupt_Enable(
+        const int nIRQ,
+        const unsigned int Flags);
+
+/*
+ * This function enables execution context (allows it to run) that services
+ * the nIRQ interrupt.
+ *
+ * Note: this function is different from the Adapter_Interrupt_Enable()
+ *       function which only enables the nIRQ interrupt event at an interrupt
+ *       controller. The interrupt can be dispatched to some execution context
+ *       (for example, a thread) that can be also enabled or disabled.
+ */
+int
+Adapter_Interrupt_Context_Enable(
+        const int nIRQ,
+        const unsigned int Flags);
+
+int
+Adapter_Interrupt_Clear(
+        const int nIRQ,
+        const unsigned int Flags);
+
+int
+Adapter_Interrupt_ClearAndEnable(
+        const int nIRQ,
+        const unsigned int Flags);
+
+int
+Adapter_Interrupt_Disable(
+        const int nIRQ,
+        const unsigned int Flags);
+
+/*
+ * This function disables execution context (allows it to run) that services
+ * the nIRQ interrupt.
+ *
+ * Note: this function is different from the Adapter_Interrupt_Disable()
+ *       function which only disables the nIRQ interrupt event at an interrupt
+ *       controller. The interrupt can be dispatched to some execution context
+ *       (for example, a thread) that can be also enabled or disabled.
+ */
+int
+Adapter_Interrupt_Context_Disable(
+        const int nIRQ,
+        const unsigned int Flags);
+
+int
+Adapter_Interrupts_Resume(void);
+
+
+// Host hardware specific extensions
+#include "adapter_interrupts_ext.h"
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_interrupts.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts_ext.h
new file mode 100644
index 0000000..9201271
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_interrupts_ext.h
@@ -0,0 +1,51 @@
+/* adapter_interrupts_ext.h
+ *
+ * Host hardware specific extensions for the Adapter Interrupts interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_INTERRUPTS_EXT_H_
+#define ADAPTER_INTERRUPTS_EXT_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Adapter EIP-202 Default configuration
+#include "c_adapter_eip202.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define ADAPTER_EIP202_ADD_IRQ(_name,_phy,_aicname,_tasklet,_pol)  \
+    _name
+
+// Adapter logical EIP-(1)97 interrupts
+enum
+{
+    ADAPTER_EIP202_IRQS
+};
+
+#undef ADAPTER_EIP202_ADD_IRQ
+
+#endif /* ADAPTER_INTERRUPTS_EXT_H_ */
+
+/* end of file adapter_interrupts_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock.h
new file mode 100644
index 0000000..421212d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock.h
@@ -0,0 +1,213 @@
+/* adapter_lock.h
+ *
+ * Adapter concurrency (locking) management
+ *
+ * Adapter_Lock functions usage examples
+ *
+ * Example 1:
+ *
+ * static Adapter_Lock_t Lock;
+ * static unsigned long Flags;
+ *
+ * Adapter_Lock_Alloc(Lock);
+ * Adapter_Lock_Acquire(Lock, &Flags);
+ * ...
+ * Adapter_Lock_Release(Lock, &Flags);
+ * Adapter_Lock_Free(Lock);
+ *
+ * Example 2:
+ *
+ * static ADAPTER_LOCK_DEFINE(Lock_p);
+ * static unsigned long Flags;
+ *
+ * Adapter_Lock_Acquire(Lock_p, &Flags);
+ * ...
+ * Adapter_Lock_Release(Lock_p, &Flags);
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_LOCK_H
+#define INCLUDE_GUARD_ADAPTER_LOCK_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Lock, use Adapter_Lock_NULL to set to a known uninitialized value
+typedef void * Adapter_Lock_t;
+
+// Critical section
+typedef struct
+{
+    volatile void * p [2]; // Place holder
+
+} Adapter_Lock_CS_t;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_t
+ *
+ * This handle can be assigned to a variable of type Adapter_Lock_t.
+ *
+ */
+extern const Adapter_Lock_t Adapter_Lock_NULL;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Alloc
+ */
+Adapter_Lock_t
+Adapter_Lock_Alloc(void);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Free
+ */
+void
+Adapter_Lock_Free(
+        Adapter_Lock_t Lock);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Acquire
+ *
+ * Acquire the lock.
+ *
+ * Lock (input):
+ *      Lock to acquire
+ *
+ * Flags (input):
+ *      Pointer to memory location where implementation-specific flags
+ *      can be stored.
+ *
+ * Return value:
+ *     none
+ */
+void
+Adapter_Lock_Acquire(
+        Adapter_Lock_t Lock,
+        unsigned long * Flags);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Release
+ *
+ * Release the lock previously acquired via Adapter_Lock_Acquire().
+ *
+ * Lock (input):
+ *      Lock to be released
+ *
+ * Flags (input):
+ *      Pointer to memory location where flags were stored by
+ *      the corresponding Adapter_Lock_Acquire() call.
+ *
+ * Return value:
+ *     none
+ */
+void
+Adapter_Lock_Release(
+        Adapter_Lock_t Lock,
+        unsigned long * Flags);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Set
+ *
+ * Set the lock for the critical section.
+ *
+ * Note: This function must be called prior to calling Adapter_Lock_CS_Enter()
+ *       or Adapter_Lock_CS_Leave() functions.
+ *       The lock cannot be changes while the critical section is entered.
+ *
+ * CS_p (output):
+ *      Critical section where the Lock data must be set.
+ *
+ * Lock (input):
+ *      Pointer to a lock instantiated by the ADAPTER_LOCK_DEFINE macro or
+ *      allocated by Adapter_Lock_Alloc() function
+ *
+ * Return value:
+ *     none
+ */
+void
+Adapter_Lock_CS_Set(
+        Adapter_Lock_CS_t * const CS_p,
+        Adapter_Lock_t Lock);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Get
+ *
+ * Get the lock for the critical section.
+ *
+ * CS_p (input):
+ *      Critical section for which the Lock object must be obtained.
+ *
+ * Return value:
+ *     Lock
+ */
+Adapter_Lock_t
+Adapter_Lock_CS_Get(
+        Adapter_Lock_CS_t * const CS_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Enter
+ *
+ * Enter critical section
+ *
+ * Return code:
+ *     true - section entered
+ *     false - section not entered, another context is already executing it
+ */
+bool
+Adapter_Lock_CS_Enter(
+        Adapter_Lock_CS_t * const CS_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Leave
+ *
+ * Leave critical section
+ *
+ * Return value:
+ *     none
+ */
+void
+Adapter_Lock_CS_Leave(
+        Adapter_Lock_CS_t * const CS_p);
+
+
+// Adapter Locking API extensions
+#include "adapter_lock_ext.h"           // ADAPTER_LOCK_DEFINE
+
+
+#endif // INCLUDE_GUARD_ADAPTER_LOCK_H
+
+
+/* end of file adapter_lock.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock_internal.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock_internal.h
new file mode 100644
index 0000000..e7a7594
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_lock_internal.h
@@ -0,0 +1,56 @@
+/* adapter_lock_internal.h
+ *
+ * Adapter concurrency (locking) management
+ * Internal interface
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_LOCK_INTERNAL_H
+#define INCLUDE_GUARD_ADAPTER_LOCK_INTERNAL_H
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Internal critical section data structure
+typedef struct
+{
+    // Generic lock pointer
+    void * Lock_p;
+
+    // True if the lock is taken
+    volatile bool fLocked;
+
+} Adapter_Lock_CS_Internal_t;
+
+
+#endif // INCLUDE_GUARD_ADAPTER_LOCK_INTERNAL_H
+
+
+/* end of file adapter_lock_internal.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pcl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pcl.h
new file mode 100644
index 0000000..d037636
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pcl.h
@@ -0,0 +1,131 @@
+/* adapter_pcl.h
+ *
+ * Adapter PCL Internal interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_PCL_INTERNAL_H
+#define INCLUDE_GUARD_ADAPTER_PCL_INTERNAL_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "basic_defs.h"         // bool
+
+// EIP-207 Driver Library
+#include "eip207_flow_generic.h"
+
+// List API
+#include "list.h"               // List_*
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter Locking internal API
+#include "adapter_lock.h"       // Adapter_Lock_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    volatile bool PCL_IsInitialized;
+    EIP207_Flow_IOArea_t * EIP207_IOArea_p;
+
+    void * EIP207_Descriptor_Area_p;
+    DMAResource_Handle_t EIP207_Hashtable_DMA_Handle;
+
+    unsigned int FreeListID;
+    List_Element_t * ElementPool_p;
+    unsigned char * RecDscrPool_p;
+
+    // Pointer to pool list
+    void * List_p;
+
+    // Pointer to elements for pool of lists
+    List_Element_t * ListElementPool_p;
+
+    // Pointer to a pool of lists
+    unsigned char * ListPool_p;
+
+    // Device-specific lock and critical section
+    Adapter_Lock_t AdapterPCL_DevLock;
+    Adapter_Lock_CS_t AdapterPCL_DevCS;
+
+} AdapterPCL_Device_Instance_Data_t;
+
+
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_Device_Get
+ *
+ * Obtain PCL Device pointer for the provided interface id
+ */
+AdapterPCL_Device_Instance_Data_t *
+AdapterPCL_Device_Get(
+        const unsigned int InterfaceId);
+
+
+/*-----------------------------------------------------------------------------
+  AdapterPCL_DMABuf_To_TRDscr
+
+  Convert DMABuf handle to Transform record descriptor
+
+  TransformHandle (input)
+    DMABuf handle representing the transform.
+
+  TR_Dscr_p (output)
+    Pointer to TR descriptor.
+
+  Rec_pp (output)
+    Pointer to memory location where pointer to DMAesource record descriptor
+    will be stored.
+
+  Return:
+      PCL_STATUS_OK if succeeded.
+      PCL_ERROR
+*/
+PCL_Status_t
+AdapterPCL_DMABuf_To_TRDscr(
+        const DMABuf_Handle_t TransformHandle,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        DMAResource_Record_t ** Rec_pp);
+
+
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_ListID_Get
+ *
+ * Obtain List pointer for the provided interface id
+ *
+ * Return:
+ *     PCL_STATUS_OK if succeeded.
+ *     PCL_ERROR
+ */
+PCL_Status_t
+AdapterPCL_ListID_Get(
+        const unsigned int InterfaceId,
+        unsigned int * const ListID_p);
+
+
+#endif /* Include Guard */
+
+
+/* end of file adapter_pcl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pec_pktbuf.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pec_pktbuf.h
new file mode 100644
index 0000000..c2d18fa
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pec_pktbuf.h
@@ -0,0 +1,104 @@
+/* adapter_pec_pktbuf.h
+ *
+ * Helper functions to access packet data via DMABuf handles, possibly
+ * in scatter-gather lists.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2020-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_PEC_PKTBUF_H_
+#define ADAPTER_PEC_PKTBUF_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"            // bool
+
+// DMABuf API
+#include "api_dmabuf.h"            // DMABuf_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PEC_PktData_Get
+ *
+ * Obtain packet data from a DMA Buf handle in a contiguous buffer.
+ * If the data already exists in a contiguous buffer, return a pointer to it.
+ * If the desired data is spread across scatter particles, copy it into supplied
+ * copy buffer.
+ *
+ * PacketHandle (input)
+ *     DMABuf handle representing the packet (either single buffer or scatter
+ *     list).
+ *
+ * CopyBuffer_p (input)
+ *     Buffer to which the packet data must be copied if not contiguous.
+ *     Can be NULL if data is assumed to be contiguous.
+ *
+ * StartOffs (input)
+ *     Byte offset from start of the packet of first byte of packet to access.
+ *
+ * ByteCount (input)
+ *     Length of packet data to access.
+ *
+ * Return:
+ *    Non-null pointer; access to packet data.
+ *    NULL pointer: scatter list does not contain desired offset or supplied
+ *                  copy buffer pointer was NULL and data was spread.
+ */
+uint8_t *
+Adapter_PEC_PktData_Get(
+        DMABuf_Handle_t PacketHandle,
+        uint8_t *CopyBuffer_p,
+        unsigned int StartOffs,
+        unsigned int ByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PEC_PktByte_Put
+ *
+ * Write single byte at specific offset in packet data represented by
+ * a DMABuf handle. This can be either a single buffer or a scatter list.
+ *
+ * PacketHandle (input)
+ *     DMABuf handle representing the packet to update.
+ *
+ * Offset (input)
+ *     Byte offset within the packet to update.
+ *
+ * Byte (input)
+ *     Byte value to write.
+ */
+void
+Adapter_PEC_PktByte_Put(
+        DMABuf_Handle_t PacketHandle,
+        unsigned int Offset,
+        unsigned int Byte);
+
+
+#endif /* ADAPTER_PEC_PKTBUF_H_ */
+
+
+/* end of file adapter_pec_pktbuf.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pecdev_dma.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pecdev_dma.h
new file mode 100644
index 0000000..7cb0db8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_pecdev_dma.h
@@ -0,0 +1,444 @@
+/* adapter_pecdev_dma.h
+ *
+ * Interface to device-specific layer of the PEC implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_PECDEV_DMA_H_
+#define ADAPTER_PECDEV_DMA_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_adapter_pec.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+// SLAD PEC API
+#include "api_pec.h"
+
+// SLAD DMABuf API
+#include "api_dmabuf.h"
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+#include "adapter_interrupts.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Capabilities_Get
+ *
+ * This routine returns a structure that describes the capabilities of the
+ * implementation. See description of PEC_Capabilities_t for details.
+ *
+ * Capabilities_p
+ *     Pointer to the capabilities structure to fill in.
+ *
+ * This function is re-entrant.
+ */
+PEC_Status_t
+Adapter_PECDev_Capabilities_Get(
+        PEC_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Control_Write
+ *
+ * Write the Control1 and Control2 engine-specific fields in the
+ * Command Descriptor The other fields (such as SrcPkt_ByteCount and
+ * Bypass_WordCount must have been filled in already.
+ *
+ * Command_p (input, output)
+ *     Command descriptor whose Control1 and Control2 fields must be filled in.
+ *
+ * PacketParams_p (input)
+ *     Per-packet parameters.
+ *
+ * This function is not implemented for all engine types.
+ */
+PEC_Status_t
+Adapter_PECDev_CD_Control_Write(
+        PEC_CommandDescriptor_t *Command_p,
+        const PEC_PacketParams_t *PacketParams_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_RD_Status_Read
+ *
+ * Read the engine-specific Status1 and Status2 fields from a Result Descriptor
+ * and convert them to an engine-independent format.
+ *
+ * Result_p (input)
+ *     Result descriptor.
+ *
+ * ResultStatus_p (output)
+ *     Engine-independent status information.
+ *
+ * Not all error conditions can occur on all engine types.
+ */
+PEC_Status_t
+Adapter_PECDev_RD_Status_Read(
+        const PEC_ResultDescriptor_t * const Result_p,
+        PEC_ResultStatus_t * const ResultStatus_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Init
+ *
+ * This function must be used to initialize the service. No API function may
+ * be used before this function has returned.
+ */
+PEC_Status_t
+Adapter_PECDev_Init(
+        const unsigned int InterfaceId,
+        const PEC_InitBlock_t * const InitBlock_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_UnInit
+ *
+ * This call un-initializes the service. Use only when there are no pending
+ * transforms. The caller must make sure that no API function is used while or
+ * after this function executes.
+ */
+PEC_Status_t
+Adapter_PECDev_UnInit(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Resume
+ *
+ * This function must be used to resume the device after it was suspended.
+ * This is a lightweight implementation of the Adapter_PECDev_Init() function.
+ */
+int
+Adapter_PECDev_Resume(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Suspend
+ *
+ * This function must be used to suspend the device after it was resumed.
+ * This is a lightweight implementation of the Adapter_PECDev_UnInit() function.
+ */
+int
+Adapter_PECDev_Suspend(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SA_Prepare
+ *
+ * This function performs device-specific preparation of the SA record(s).
+ *
+ * At this point the SA Record is stored in memory in the byte order
+ * required by the hardware, which may be different from the host byte order.
+ * Hence any accesses must be done with DMAResource_Read32() and
+ * DMAResource_Write32().
+ *
+ * Note: The resource is not owned by the hardware yet.
+ *
+ * SAHandle (input)
+ *   DMA handle representing the main SA Record.
+ *
+ * StateHandle (input)
+ *   DMA handle representing the State Record (null handle if not in use)
+ *
+ * ARC4Handle (input)
+ *   DMA handle representing the ARC4 State Record (null handle if not in use)
+ *
+ * Return code
+ *   See PEC_Status_t
+ */
+PEC_Status_t
+Adapter_PECDev_SA_Prepare(
+        const DMABuf_Handle_t SAHandle,
+        const DMABuf_Handle_t StateHandle,
+        const DMABuf_Handle_t ARC4Handle);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SA_Remove
+ *
+ * This function performs device-specific removal of the SA record(s).
+ *
+ * SAHandle (input)
+ *   DMA handle representing the main SA Record.
+ *
+ * StateHandle (input)
+ *   DMA handle representing the State Record (null handle if not in use)
+ *
+ * ARC4Handle (input)
+ *   DMA handle representing the ARC4 State Record (null handle if not in use)
+ *
+ * At this point the SA record is stored in memory in the byte order
+ * required by the hardware, which may be different from the host byte order.
+ * Hence any accesses must be done with DMAResource_Read32() and
+ * DMAResource_Read32().
+ *
+ * Note: The record is not owned by the hardware anymore.
+ *
+ * Return code
+ *   See PEC_Status_t
+ */
+PEC_Status_t
+Adapter_PECDev_SA_Remove(
+        const DMABuf_Handle_t SAHandle,
+        const DMABuf_Handle_t StateHandle,
+        const DMABuf_Handle_t ARC4Handle);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_GetFreeSpace
+ *
+ * Return the number of free slots in the indicated ring. When
+ * Adapter_PECDev_PacketPut is called with no more than that many
+ * valid command descriptors and none of these require scatter/gather,
+ * the operation is guaranteed to succeed, unless a fatal error
+ * happens in the meantime.
+ */
+unsigned int
+Adapter_PECDev_GetFreeSpace(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_PacketPut
+ *
+ * Submit one or more non-scatter-gather packets to the device.
+ *
+ * InterfaceId (input)
+ *     Represents the ring to which packets are submitted.
+ *
+ * Commands_p (input)
+ *     Pointer to one (or an array of command descriptors, each describe one
+ *     transform request.
+ *
+ * CommandsCount (input)
+ *     The number of command descriptors pointed to by Commands_p.
+ *
+ * PutCount_p (output)
+ *     This parameter is used to return the actual number of descriptors that
+ *     was queued up for processing (0..CommandsCount).
+ *
+ * If bounce buffers were required for any of the DMA resources, the
+ * supplied handles contain the BounceHandle field in their DMA
+ * resource records and the data has been copied to bounce
+ * buffers. The packet token is stored in the DMA buffer in the
+ * required byte order (this is the case for all DMA resources). All
+ * DMA resources are owned by the hardware.
+ */
+PEC_Status_t
+Adapter_PECDev_Packet_Put(
+        const unsigned int InterfaceId,
+        const PEC_CommandDescriptor_t * Commands_p,
+        const unsigned int CommandsCount,
+        unsigned int * const PutCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Packet_Get
+ *
+ * Retrieve zero or more non-scatter-gather packets from the device.
+ *
+ * InterfaceId (input)
+ *     Represents the ring to which packets are submitted.
+ *
+ * Results_p (input)
+ *     Pointer to the result descriptor, or array of result descriptors, that
+ *     will be populated by the service based on completed transform requests.
+ *
+ * ResultsLimit (input)
+ *     The number of result descriptors available from Results_p and onwards.
+ *
+ * GetCount_p (output)
+ *     The actual number of result descriptors that were populated is returned
+ *     in this parameter.
+ *
+ * Only the DstPkt_ByteCount, Status1 and Status2 fields will be filled in for
+ * each result descriptor. All DMA resources are still owned by the hardware.
+ */
+PEC_Status_t
+Adapter_PECDev_Packet_Get(
+        const unsigned int InterfaceId,
+        PEC_ResultDescriptor_t * Results_p,
+        const unsigned int ResultsLimit,
+        unsigned int * const GetCount_p);
+
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_TestSG
+ *
+ * Test whether a single packet with the indicated number of gather
+ * particles and scatter particles can be processed successfully on
+ * the indicated ring.
+ *
+ * If GatherParticleCount is zero, the packet does not use Gather.
+ * If ScatterParticleCount is zero, the packet does not use Scatter.
+ */
+bool
+Adapter_PECDev_TestSG(
+        const unsigned int InterfaceId,
+        const unsigned int GatherParticleCount,
+        const unsigned int ScatterParticleCount);
+#endif // ADAPTER_PEC_ENABLE_SCATTERGATHER
+
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_IRQToInteraceID
+ *
+ * Convert the interrupt number to the Interface ID for which this
+ * interrupt was generated.
+ */
+unsigned int
+Adapter_PECDev_IRQToInferfaceId(
+        const int nIRQ);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Enable_ResultIRQ
+ *
+ * Enable the interrupt or interrupts for available result packets on the
+ * specified interface.
+ */
+void
+Adapter_PECDev_Enable_ResultIRQ(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Disable_ResultIRQ
+ *
+ * Disable the interrupt or interrupts for available result packets on the
+ * specified interface.
+ */
+void
+Adapter_PECDev_Disable_ResultIRQ(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Enable_CommandIRQ
+ *
+ * Enable the interrupt or interrupts that indicate that the specified
+ * interface can accept commands.
+ */
+void
+Adapter_PECDev_Enable_CommandIRQ(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Disable_CommandIRQ
+ *
+ * Disable the interrupt or interrupts that indicate that the specified
+ * interface can accept commands.
+ */
+void
+Adapter_PECDev_Disable_CommandIRQ(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SetResultHandler
+ *
+ * Set a handler function for the result interrupt on the indicated
+ * interface.
+ */
+void Adapter_PECDev_SetResultHandler(
+    const unsigned int InterfaceId,
+    Adapter_InterruptHandler_t HandlerFunction);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SetCommandHandler
+ *
+ * Set a handler function for the command interrupt on the indicated
+ * interface.
+ */
+void Adapter_PECDev_SetCommandHandler(
+        const unsigned int InterfaceId,
+        Adapter_InterruptHandler_t HandlerFunction);
+#endif // ADAPTER_PEC_INTERRUPTS_ENABLE
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Scatter_Preload
+ *
+ * This function must be used to pre-load the service with scatter buffers
+ * that will be consumed by transforms configured to use scatter buffers
+ * instead of a provided destination buffer(s). This is required for certain
+ * engines only - check the driver documentation.
+ *
+ * InterfaceId (input)
+ *    Packet I/O interface (such as ring, for example) for which scatter buffers
+ *    must be pre-loaded.
+ *
+ * Handles_p (input)
+ *     Pointer to an array of handles, each handle representing one scatter
+ *     buffer.
+ *
+ * HandlesCount (input)
+ *     The number of handles in the array pointed to by Handles_p.
+ */
+PEC_Status_t
+Adapter_PECDev_Scatter_Preload(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t * Handles_p,
+        const unsigned int HandlesCount);
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Put_Dump
+ *
+ * Dump the administration data of the packet put operation.
+ */
+void
+Adapter_PECDev_Put_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpCDRAdmin,
+        const bool fDumpCDRCache);
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Get_Dump
+ *
+ * Dump the administration data of the packet get operation.
+ */
+void
+Adapter_PECDev_Get_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpRDRAdmin,
+        const bool fDumpRDRCache);
+
+
+#endif /* ADAPTER_PECDEV_DMA_H_ */
+
+
+/* end of file adapter_pecdev_dma.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_rc_eip207.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_rc_eip207.h
new file mode 100644
index 0000000..5442741
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_rc_eip207.h
@@ -0,0 +1,63 @@
+/* adapter_rc_eip207.h
+ *
+ * Interface to Security-IP-207 Record Cache functionality.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_RC_EIP207_H_
+#define ADAPTER_RC_EIP207_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_RC_EIP207_Configure
+ *
+ * This routine configures the Security-IP-207 Record Cache functionality
+ * with EIP-207 HW parameters that can be obtained via the HW datasheet or
+ * the Security-IP-207 Global Control interface, for example.
+ *
+ * fEnabledTRC (input)
+ *         True when the EIP-207 Transform Record Cache is enabled
+ *
+ * fEnabledARC4RC (input)
+ *         True when the EIP-207 ARC4 Record Cache is enabled
+ *
+ * fCombined (input)
+ *         True when the EIP-207 TRC and ARC4RC are combined
+ *
+ * This function is re-entrant.
+ */
+void
+Adapter_RC_EIP207_Configure(
+        const bool fEnabledTRC,
+        const bool fEnabledARC4RC,
+        const bool fCombined);
+
+
+#endif /* ADAPTER_RC_EIP207_H_ */
+
+
+/* end of file adapter_rc_eip207.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_ring_eip202.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_ring_eip202.h
new file mode 100644
index 0000000..63a7303
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_ring_eip202.h
@@ -0,0 +1,66 @@
+/* adapter_ring_eip202.h
+ *
+ * Interface to EIP-202 ring-specific functionality.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_RING_EIP202_H_
+#define ADAPTER_RING_EIP202_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Ring_EIP202_Configure
+ *
+ * This routine configures the Security-IP-202 ring-specific functionality
+ * with parameters that are obtained via the Global Control
+ * interface.
+ *
+ * HostDataWidth (input)
+ *         Host interface data width:
+ *              0 = 32 bits, 1 = 64 bits, 2 = 128 bits, 3 = 256 bits
+ *
+ * CF_Size (input)
+ *         Command Descriptor FIFO size, the actual size is 2^CF_Size 32-bit
+ *         words.
+ *
+ * RF_Size (input)
+ *         Result Descriptor FIFO size, the actual size is 2^RF_Size 32-bit
+ *         words.
+ *
+ * This function is re-entrant.
+ */
+void
+Adapter_Ring_EIP202_Configure(
+        const uint8_t HostDataWidth,
+        const uint8_t CF_Size,
+        const uint8_t RF_Size);
+
+
+#endif /* ADAPTER_RING_EIP202_H_ */
+
+
+/* end of file adapter_ring_eip202.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_sleep.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_sleep.h
new file mode 100644
index 0000000..c24101e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/adapter_sleep.h
@@ -0,0 +1,47 @@
+/* adapter_sleep.h
+ *
+ * Data types and Interfaces
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_SLEEP_H
+#define INCLUDE_GUARD_ADAPTER_SLEEP_H
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+/*----------------------------------------------------------------------------
+ *                           Adapter time management
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * Adapter_SleepMS
+ *
+ * This function will sleep the calling context for at most the requested
+ * amount of time (milliseconds) and then returns.
+ *
+ */
+void
+Adapter_SleepMS(
+        const unsigned int Duration_ms);
+
+#endif /* Include Guard */
+
+/* end of file adapter_sleep.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_dmabuf.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_dmabuf.h
new file mode 100644
index 0000000..ab20069
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_dmabuf.h
@@ -0,0 +1,233 @@
+/* api_dmabuf.h
+ *
+ * Management of buffers that can be shared between the host and hardware
+ * devices that utilize Direct Memory Access (DMA).
+ *
+ * Issues to take into account for these buffers:
+ * - Start address alignment
+ * - Cache line sharing for buffer head and tail
+ * - Cache coherence
+ * - Address translation to device memory view
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_API_DMABUF_H
+#define INCLUDE_GUARD_API_DMABUF_H
+
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Handle_t
+ *
+ * This handle is a reference to a DMA buffer. It is returned when a buffer
+ * is allocated or registered and it remains valid until the buffer is freed
+ * or de-registered.
+ *
+ * The handle is set to NULL when DMABuf_Handle_t handle.p is equal to NULL.
+ *
+ */
+typedef struct
+{
+    void * p;
+} DMABuf_Handle_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_HostAddress_t
+ *
+ * Buffer address that can be used by the host to access the buffer. This
+ * address has been put in a data structure to make it type-safe.
+ */
+typedef struct
+{
+    void * p;
+} DMABuf_HostAddress_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Status_t
+ *
+ * Return values for all the API functions.
+ */
+typedef enum
+{
+    DMABUF_STATUS_OK,
+    DMABUF_ERROR_BAD_ARGUMENT,
+    DMABUF_ERROR_INVALID_HANDLE,
+    DMABUF_ERROR_OUT_OF_MEMORY
+} DMABuf_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Properties_t
+ *
+ * Buffer properties. When allocating a buffer, these are the requested
+ * properties for the buffer. When registering an externally allocated buffer,
+ * these properties describe the buffer.
+ *
+ * For both uses, the data structure should be initialized to all zeros
+ * before filling in some or all of the fields. This ensures forward
+ * compatibility in case this structure is extended with more fields.
+ *
+ * Example usage:
+ *     DMABuf_Properties_t Props = {0};
+ *     Props.fIsCached = true;
+ */
+typedef struct
+{
+    uint32_t Size;       // size of the buffer
+    uint8_t Alignment;   // buffer start address alignment, for example
+                         // 4 for 32bit
+    uint8_t Bank;        // can be used to indicate on-chip memory
+    bool fCached;        // true = SW needs to do coherency management
+} DMABuf_Properties_t;
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_NULLHandle
+ *
+ * This handle can be assigned to a variable of type DMABuf_Handle_t.
+ *
+ */
+extern const DMABuf_Handle_t DMABuf_NULLHandle;
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Handle_IsSame
+ *
+ * Check whether provided Handle1 is equal to provided Handle2.
+ *
+ * Handle1_p
+ *      First handle
+ *
+ * Handle2_p
+ *      Second handle
+ *
+ * Return values
+ *      true:  provided handles are equal
+ *      false: provided handles are not equal
+ *
+ */
+bool
+DMABuf_Handle_IsSame(
+        const DMABuf_Handle_t * const Handle1_p,
+        const DMABuf_Handle_t * const Handle2_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Alloc
+ *
+ * Allocate a buffer of requested size that can be used for device DMA.
+ *
+ * RequestedProperties
+ *     Requested properties of the buffer that will be allocated, including
+ *     the size, start address alignment, etc. See above.
+ *
+ * Buffer_p (output)
+ *     Pointer to the memory location where the address of the buffer will be
+ *     written by this function when allocation is successful. This address
+ *     can then be used to access the driver on the host in the domain of the
+ *     driver.
+ *
+ * Handle_p (output)
+ *     Pointer to the memory location when the handle will be returned.
+ *
+ * Return Values
+ *     DMABUF_STATUS_OK: Success, Handle_p was written.
+ *     DMABUF_ERROR_BAD_ARGUMENT
+ *     DMABUF_ERROR_OUT_OF_MEMORY: Failed to allocate a buffer or handle.
+ */
+DMABuf_Status_t
+DMABuf_Alloc(
+        const DMABuf_Properties_t RequestedProperties,
+        DMABuf_HostAddress_t * const Buffer_p,
+        DMABuf_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Register
+ *
+ * This function must be used to register an "alien" buffer that was allocated
+ * somewhere else.
+ *
+ * ActualProperties (input)
+ *     Properties that describe the buffer that is being registered.
+ *
+ * Buffer_p (input)
+ *     Pointer to the buffer. This pointer must be valid to use on the host
+ *     in the domain of the driver.
+ *
+ * Alternative_p (input)
+ *     Some allocators return two addresses. This parameter can be used to
+ *     pass this second address to the driver. The type is pointer to ensure
+ *     it is always large enough to hold a system address, also in LP64
+ *     architecture. Set to NULL if not used.
+ *
+ * AllocatorRef (input)
+ *     Number to describe the source of this buffer. The exact numbers
+ *     supported is implementation specific. This provides some flexibility
+ *     for a specific implementation to support a number of "alien" buffers
+ *     from different allocator and properly interpret and use the
+ *     Alternative_p parameter when translating the address to the device
+ *     memory map. Set to zero when a default allocator is used. The type
+ *     of the default allocator is implementation specific,
+ *     refer to the DMABuf API Implementation Notes for details.
+ *
+ * Handle_p (output)
+ *     Pointer to the memory location when the handle will be returned.
+ *
+ * Return Values
+ *     DMABUF_STATUS_OK: Success, Handle_p was written.
+ *     DMABUF_ERROR_BAD_ARGUMENT
+ *     DMABUF_ERROR_OUT_OF_MEMORY: Failed to allocate a handle.
+ */
+DMABuf_Status_t
+DMABuf_Register(
+        const DMABuf_Properties_t ActualProperties,
+        void * Buffer_p,
+        void * Alternative_p,
+        const char AllocatorRef,
+        DMABuf_Handle_t * const Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Release
+ *
+ * This function will close the handle that was returned by DMABuf_Alloc or
+ * DMABuf_Register, meaning it must not be used anymore.
+ * If the buffer was allocated through DMABuf_Alloc, this function will also
+ * free the buffer, meaning it must not be accessed anymore.
+ *
+ * Handle (input)
+ *     The handle that may be released.
+ *
+ * Return Values
+ *     DMABUF_STATUS_OK
+ *     DMABUF_ERROR_INVALID_HANDLE
+ */
+DMABuf_Status_t
+DMABuf_Release(
+        DMABuf_Handle_t Handle);
+
+
+#endif /* Include Guard */
+
+/* end of file api_dmabuf.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_init.h
new file mode 100644
index 0000000..03c80d6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_init.h
@@ -0,0 +1,51 @@
+/* api_driver197_init.h
+ *
+ * Security-IP-197 Driver Initialization Interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DRIVER197_INIT_H_
+#define DRIVER197_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Init
+ *
+ * Initialize the driver. This function must be called before any other
+ * driver API function can be called.
+ *
+ * Returns 0 for success and -1 for failure.
+ */
+int
+Driver197_Init(void);
+
+/*----------------------------------------------------------------------------
+ * Driver197_Exit
+ *
+ * Initialize the driver. After this function is called no other driver API
+ * function can be called except Driver197_Init().
+ */
+void
+Driver197_Exit(void);
+
+
+#endif /* DRIVER197_INIT_H_ */
+
+
+/* end of file api_driver197_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_init.h
new file mode 100644
index 0000000..bacd638
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_init.h
@@ -0,0 +1,51 @@
+/* api_driver197_pec_init.h
+ *
+ * Security-IP-197 Driver Initialization or PEC only Interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_DRIVER197_PEC_INIT_H_
+#define API_DRIVER197_PEC_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_Init
+ *
+ * Initialize the driver. This function must be called before any other
+ * driver API function can be called.
+ *
+ * Returns 0 for success and -1 for failure.
+ */
+int
+Driver197_PEC_Init(void);
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_Exit
+ *
+ * Initialize the driver. After this function is called no other driver API
+ * function can be called except Driver197_Init().
+ */
+void
+Driver197_PEC_Exit(void);
+
+
+#endif /* API_DRIVER197_PEC_INIT_H_ */
+
+
+/* end of file api_driver197_pec_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_pcl_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_pcl_init.h
new file mode 100644
index 0000000..ded492d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_driver197_pec_pcl_init.h
@@ -0,0 +1,51 @@
+/* api_driver197_pec_pcl_init.h
+ *
+ * Security-IP-197 Driver Initialization or PEC_PCL only Interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_DRIVER197_PEC_PCL_INIT_H_
+#define API_DRIVER197_PEC_PCL_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_PCL_Init
+ *
+ * Initialize the driver. This function must be called before any other
+ * driver API function can be called.
+ *
+ * Returns 0 for success and -1 for failure.
+ */
+int
+Driver197_PEC_PCL_Init(void);
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_PCL_Exit
+ *
+ * Initialize the driver. After this function is called no other driver API
+ * function can be called except Driver197_Init().
+ */
+void
+Driver197_PEC_PCL_Exit(void);
+
+
+#endif /* API_DRIVER197_PEC_PCL_INIT_H_ */
+
+
+/* end of file api_driver197_pec_pcl_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_driver197_init.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_driver197_init.h
new file mode 100644
index 0000000..3b4888b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_driver197_init.h
@@ -0,0 +1,52 @@
+/* api_global_driver197_init.h
+ *
+ * Security-IP-197 Global Control Driver Initialization Interface
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef DRIVER197_GLOBAL_INIT_H_
+#define DRIVER197_GLOBAL_INIT_H_
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Global_Init
+ *
+ * Initialize the global control driver. This function must be called before
+ * any other driver API function can be called.
+ *
+ * Returns 0 for success and -1 for failure.
+ */
+int
+Driver197_Global_Init(void);
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Global_Exit
+ *
+ * Uninitialize the global control driver. After this function is called
+ * no other driver API function can be called except Driver197_Global_Init().
+ */
+void
+Driver197_Global_Exit(void);
+
+
+#endif /* DRIVER197_GLOBAL_INIT_H_ */
+
+
+/* end of file api_driver197_init.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip207.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip207.h
new file mode 100644
index 0000000..871e07f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip207.h
@@ -0,0 +1,122 @@
+/* api_global_eip207.h
+ *
+ * Classification (EIP-207) Global Control Initialization API
+ *
+ * This API is not re-entrant.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_GLOBAL_EIP207_H_
+#define API_GLOBAL_EIP207_H_
+
+
+// The status part of the API
+#include "api_global_status_eip207.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t, bool
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_GLOBAL_CONTROL_MAXLEN_TEXT           128
+
+// IV to use for the Flow Hash ID calculations by the Classification hardware
+typedef struct
+{
+    uint32_t IV[4]; // must be written with a true random value
+} GlobalControl207_IV_t;
+
+// Zero-terminated descriptive text of the available services.
+typedef struct
+{
+    char szTextDescription[EIP207_GLOBAL_CONTROL_MAXLEN_TEXT];
+} GlobalControl207_Capabilities_t;
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Capabilities_Get
+ *
+ * This functions retrieves info about the capabilities of the
+ * implementation.
+ *
+ * Capabilities_p
+ *     Pointer to the capabilities structure to fill in.
+ *
+ * Return value
+ *     None
+ */
+void
+GlobalControl207_Capabilities_Get(
+        GlobalControl207_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Init
+ *
+ * This function performs the initialization of the EIP-207 Classification
+ * Engine.
+ *
+ * fLoadFirmware (input)
+ *     Flag indicates whether the EIP-207 Classification Engine firmware
+ *     must be loaded
+ *
+ * IV_p (input)
+ *     Pointer to the Initialization Vector data.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : initialization performed successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_INTERNAL : initialization failed
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_USE_ORDER : initialization is already
+ *                                                 done
+ */
+GlobalControl207_Error_t
+GlobalControl207_Init(
+        const bool fLoadFirmware,
+        const GlobalControl207_IV_t * const IV_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_UnInit
+ *
+ * This function performs the un-initialization of the EIP-207 Classification
+ * Engine.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : un-initialization performed successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_INTERNAL : un-initialization failed
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_USE_ORDER : un-initialization is already
+ *                                                 done
+ */
+GlobalControl207_Error_t
+GlobalControl207_UnInit(void);
+
+
+#endif /* API_GLOBAL_EIP207_H_ */
+
+
+/* end of file api_global_eip207.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip74.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip74.h
new file mode 100644
index 0000000..b8630fe
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip74.h
@@ -0,0 +1,269 @@
+/* api_global_eip74.h
+ *
+ * Deterministic Random Bit Generator (EIP-74) Global Control Initialization
+ * API. The EIP-74 is used to generate pseudo-random IVs for outbound
+ * operations in CBC mode.
+ *
+ * This API is not re-entrant.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_GLOBAL_EIP74_H_
+#define API_GLOBAL_EIP74_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint8_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// GlobalControl74 Error Codes
+typedef enum
+{
+    GLOBAL_CONTROL_EIP74_NO_ERROR = 0,
+    GLOBAL_CONTROL_EIP74_ERROR_BAD_PARAMETER,
+    GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER,
+    GLOBAL_CONTROL_EIP74_ERROR_INTERNAL,
+    GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED
+} GlobalControl74_Error_t;
+
+
+#define GLOBAL_CONTROL_EIP74_MAXLEN_TEXT           128
+
+// Zero-terminated descriptive text of the available services.
+typedef struct
+{
+    char szTextDescription[GLOBAL_CONTROL_EIP74_MAXLEN_TEXT];
+} GlobalControl74_Capabilities_t;
+
+
+// Configuration parameters for EIP-74.
+typedef struct
+{
+    // Number of IVs generated for each Generate operation.
+    // Value can be set to zero to request default value.
+    unsigned int GenerateBlockSize;
+
+    // Number of Generate operations after which it is an error to continue
+    // without reseed
+    // Value can be set to zero to request default value.
+    unsigned int ReseedThr;
+
+    // Number of Generate operations after which to notify that reseed is
+    // required
+    // Value can be set to zero to request default value.
+    unsigned int ReseedThrEarly;
+
+    // Detect stuck-out faults
+    bool fStuckOut;
+} GlobalControl74_Configuration_t;
+
+
+// Status information of the EIP-74.
+typedef struct
+{
+    // Number of generate operations since last initialize or reseed
+    unsigned int GenerateBlockCount;
+
+    // Stuck-out fault detected
+    bool fStuckOut;
+
+    // Not-initialized error detected
+    bool fNotInitialized;
+
+    // Reseed error  detected, GenerateBlockCount passed threshold
+    bool fReseedError;
+
+    // Reseed warning detected, GenerateBlockCount passed early  threshold
+    bool fReseedWarning;
+
+    // DRBG was instantiated successfully
+    bool fInstantiated;
+
+    // Number of IVs available
+    unsigned int AvailableCount;
+} GlobalControl74_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_NotifyFunction_t
+ *
+ * This type specifies the callback function prototype for the function
+ * GlobalControl74_Notify_Request. The notification will occur only once.
+ *
+ * NOTE: The exact context in which the callback function is invoked and the
+ *       allowed actions in that callback are implementation specific. The
+ *       intention is that all API functions can be used, except
+ *       GlobalControl74_UnInit.
+ */
+typedef void (* GlobalControl74_NotifyFunction_t)(void);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Capabilities_Get
+ *
+ * This functions retrieves info about the capabilities of the
+ * implementation.
+ *
+ * Capabilities_p
+ *     Pointer to the capabilities structure to fill in.
+ *
+ * Return value
+ *     None
+ */
+void
+GlobalControl74_Capabilities_Get(
+        GlobalControl74_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Init
+ *
+ * This function performs the initialization of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Configuration_p (input)
+ *     Configuration parameters of the DRBG.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 48 bytes that serves as the entropy.
+ *     to initialize the DRBG.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : initialization performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_PARAMETER : Invalid parameters supplied
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : initialization failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : initialization is already
+ *                                                done
+ */
+GlobalControl74_Error_t
+GlobalControl74_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_UnInit
+ *
+ * This function performs the un-initialization of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : un-initialization performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : un-initialization failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : un-initialization is already
+ *                                                done
+ */
+GlobalControl74_Error_t
+GlobalControl74_UnInit(void);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Reseed
+ *
+ * This function performs a reseed of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 48 bytes that serves as the entropy.
+ *     to reseed the DRBG.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : operation performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_PARAMETER : Invalid parameter supplied
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : device not initialized
+ */
+GlobalControl74_Error_t
+GlobalControl74_Reseed(
+        const uint8_t * const Entropy_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Status_Get
+ *
+ * This function reads the status of the EIP-74 Deterministic Random
+ * Bit Generator.
+ *
+ * Status_p (output)
+ *     Status information obtained from the EIP-74.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : operation performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_PARAMETER : Invalid parameter supplied
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : device not initialized
+ */
+GlobalControl74_Error_t
+GlobalControl74_Status_Get(
+        GlobalControl74_Status_t * const Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Clear
+ *
+ * This function clears any stuck-out condition of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : operation performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : device not initialized
+ */
+GlobalControl74_Error_t
+GlobalControl74_Clear(void);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Notify_Request
+ *
+ * This routine can be used to request a one-time notification of
+ * EIP-74 related events. When any error, fault or warning condition
+ * occurs, the implementation will invoke the callback once to notify
+ * the user. The callback function can then call
+ * GlobalControl74_Status_Get to find out what event occurred and it
+ * can take any actions to rectify the situation, to log the event or
+ * to stop processing. The callback can call this function again to
+ * request future notifications of future events.
+ *
+ * CBFunc_p (input)
+ *     Address of the callback function.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : operation performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_PARAMETER : Invalid parameter supplied
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_EIP74_ERROR_BAD_USE_ORDER : device not initialized
+ */
+GlobalControl74_Error_t
+GlobalControl74_Notify_Request(
+        GlobalControl74_NotifyFunction_t CBFunc_p);
+
+
+#endif /* API_GLOBAL_EIP74_H_ */
+
+
+/* end of file api_global_eip74.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip97.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip97.h
new file mode 100644
index 0000000..69f04f8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_eip97.h
@@ -0,0 +1,145 @@
+/* api_global_eip97.h
+ *
+ * Security-IP-97 Global Control API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_GLOBAL_EIP97_H_
+#define API_GLOBAL_EIP97_H_
+
+// The status part of the API
+#include "api_global_status_eip97.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// EIP-97 Driver Library Global API
+#include "eip97_global_init.h"  // Initialization
+#include "eip97_global_prng.h"  // PRNG
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define GLOBAL_CONTROL_MAXLEN_TEXT      128
+
+// Ring PE assignment map
+typedef EIP97_Global_Ring_PE_Map_t      GlobalControl97_Ring_PE_Map_t;
+
+// Zero-terminated descriptive text of the available services.
+typedef struct
+{
+    char szTextDescription[GLOBAL_CONTROL_MAXLEN_TEXT];
+} GlobalControl97_Capabilities_t;
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Capabilities_Get
+ *
+ * This routine returns a structure that describes the capabilities of the
+ * implementation. See description of GlobalControl97_Capabilities_t
+ * for details.
+ *
+ * Capabilities_p
+ *     Pointer to the capabilities structure to fill in.
+ *
+ * This function is re-entrant.
+ */
+GlobalControl97_Error_t
+GlobalControl97_Capabilities_Get(
+        GlobalControl97_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Init
+ *
+ * This function performs the initialization of the EIP-97 Global Control
+ * functionality.
+ *
+ * fHWResetDone (input)
+ *     Flag indicates whether the HW Reset operation was performed
+ *     for the Security-IP-97 hardware before calling this function
+ *
+ * This function is not re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : initialization performed successfully
+ *     GLOBAL_CONTROL_ERROR_INTERNAL : initialization failed
+ *     GLOBAL_CONTROL_ERROR_BAD_USE_ORDER : initialization is already done
+ */
+GlobalControl97_Error_t
+GlobalControl97_Init(
+        const bool fHWResetDone);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_UnInit
+ *
+ * This function performs the initialization of the EIP-97 Global Control
+ * functionality.
+ *
+ * This function is not re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : un-initialization performed successfully
+ *     GLOBAL_CONTROL_ERROR_INTERNAL : un-initialization failed
+ *     GLOBAL_CONTROL_ERROR_BAD_USE_ORDER : un-initialization is already done
+ */
+GlobalControl97_Error_t
+GlobalControl97_UnInit(void);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Configure
+ *
+ * This function performs the Ring to PE assignment and configures
+ * the Ring priority. The EIP-97 device supports multiple Ring interfaces
+ * as well as multiple PE's. One ring can be assigned to the same or different
+ * PE's. Multiple rings can be assigned to the same PE.
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * RingPEMap_p (input)
+ *     Pointer to the data structure that contains the Ring PE assignment map.
+ *
+ * This function is not re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : PE configured successfully
+ *     GLOBAL_CONTROL_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_Configure(
+        const unsigned int PE_Number,
+        const GlobalControl97_Ring_PE_Map_t * const RingPEMap_p);
+
+
+#endif /* API_GLOBAL_EIP97_H_ */
+
+
+/* end of file api_global_eip97.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip207.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip207.h
new file mode 100644
index 0000000..e48aa07
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip207.h
@@ -0,0 +1,171 @@
+/* api_global_status_eip207.h
+ *
+ * Classification (EIP-207) Global Control Status API
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_GLOBAL_STATUS_EIP207_H_
+#define API_GLOBAL_STATUS_EIP207_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t, bool
+
+// EIP-207 Driver Library Global Classification Control API
+#include "eip207_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// GlobalControl207 Error Codes
+typedef enum
+{
+    EIP207_GLOBAL_CONTROL_NO_ERROR = 0,
+    EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER,
+    EIP207_GLOBAL_CONTROL_ERROR_BAD_USE_ORDER,
+    EIP207_GLOBAL_CONTROL_ERROR_INTERNAL,
+    EIP207_GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED
+} GlobalControl207_Error_t;
+
+// EIP-207s FRC/TRC/ARC4RC status information
+typedef struct
+{
+    // True when a Host bus master read access from this cache
+    // resulted in an error.
+    bool fDMAReadError;
+
+    // True when a Host bus master write access from this cache
+    // resulted in an error.
+    bool fDMAWriteError;
+
+} GlobalControl207_CacheStatus_t;
+
+// Classification Engine Status information
+typedef EIP207_Global_Status_t GlobalControl207_Status_t;
+
+// The Classification hardware global statistics
+typedef EIP207_Global_GlobalStats_t GlobalControl207_GlobalStats_t;
+
+// The Classification Engine clock count
+typedef EIP207_Global_Clock_t GlobalControl207_Clock_t;
+
+// The Classification Engine firmware configuration.
+typedef EIP207_Firmware_Config_t GlobalControl_Firmware_Config_t;
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Status_Get
+ *
+ * This function retrieves the global status information
+ * from the EIP-207 Classification Engine hardware.
+ *
+ * This function can detect the EIP-207 Fatal Error condition requiring
+ * the Global SW or HW Reset!
+ *
+ * CE_Number (input)
+ *     Number of the EIP-207 Classification Engine for which the status
+ *     information must be retrieved
+ *
+ * Status_p (output)
+ *     Pointer to the data structure where the engine status will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl207_Error_t
+GlobalControl207_Status_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_Status_t * const Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_GlobalStats_Get
+ *
+ * This function obtains global statistics for the Classification Engine.
+ *
+ * CE_Number (input)
+ *     Number of the EIP-207 Classification Engine for which the global
+ *     statistics must be retrieved
+ *
+ * GlobalStats_p (output)
+ *     Pointer to the data structure where the global statistics will be stored.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : statistics retrieved successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl207_Error_t
+GlobalControl207_GlobalStats_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_GlobalStats_t * const GlobalStats_p);
+
+
+/*--------------------- -------------------------------------------------------
+ * GlobalControl207_ClockCount_Get
+ *
+ * Retrieve the current clock count as used by the Classification Engine.
+ *
+ * CE_Number (input)
+ *     Number of the EIP-207 Classification Engine for which the clock
+ *     count must be retrieved
+ *
+ * Clock_p (output)
+ *     Pointer to the data structure where the current clock count used by
+ *     the Classification Engine will be stored.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl207_Error_t
+GlobalControl207_ClockCount_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_Clock_t * const Clock_p);
+
+
+/*--------------------- -------------------------------------------------------
+ * GlobalControl207_Firmware_Configure
+ *
+ * This function configures firmware settings.
+ *
+ * FWConfig_p (input)
+ *     Configuration parameters for the firmware.
+ *
+ * Return value
+ *     EIP207_GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl207_Error_t
+GlobalControl207_Firmware_Configure(
+        GlobalControl_Firmware_Config_t * const FWConfig_p);
+
+
+#endif /* API_GLOBAL_STATUS_EIP207_H_ */
+
+
+/* end of file api_global_status_eip207.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip97.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip97.h
new file mode 100644
index 0000000..6ac6f6a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_global_status_eip97.h
@@ -0,0 +1,349 @@
+/* api_global_status_eip97.h
+ *
+ * Security-IP-97 Global Control Get Status API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef API_GLOBAL_STATUS_EIP97_H_
+#define API_GLOBAL_STATUS_EIP97_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// EIP-97 Driver Library API
+#include "eip97_global_event.h" // Event Control
+#include "eip97_global_prng.h"  // PRNG
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// GlobalControl97 Error Codes
+typedef enum
+{
+    GLOBAL_CONTROL_NO_ERROR = 0,
+    GLOBAL_CONTROL_ERROR_BAD_PARAMETER,
+    GLOBAL_CONTROL_ERROR_BAD_USE_ORDER,
+    GLOBAL_CONTROL_ERROR_INTERNAL,
+    GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED
+} GlobalControl97_Error_t;
+
+// EIP-97 Data Fetch Engine (DFE) thread status,
+// 1 DFE thread corresponds to 1 Processing Engine (PE)
+typedef EIP97_Global_DFE_Status_t GlobalControl97_DFE_Status_t;
+
+// EIP-97 Data Store Engine (DSE) thread status,
+// 1 DSE thread corresponds to 1 Processing Engine (PE)
+typedef EIP97_Global_DSE_Status_t GlobalControl97_DSE_Status_t;
+
+// EIP-96 Token Status
+typedef EIP96_Token_Status_t GlobalControl97_Token_Status_t;
+
+// EIP-96 Context Status
+typedef EIP96_Context_Status_t GlobalControl97_Context_Status_t;
+
+// EIP-96 Interrupt Status
+typedef EIP96_Interrupt_Status_t GlobalControl97_Interrupt_Status_t;
+
+// EIP-96 Output Transfer Status
+typedef EIP96_Output_Transfer_Status_t GlobalControl97_Output_Transfer_Status_t;
+
+// EIP-96 PRNG Status
+typedef EIP96_PRNG_Status_t GlobalControl97_PRNG_Status_t;
+
+// EIP-96 PRNG Re-seed data
+typedef EIP96_PRNG_Reseed_t             GlobalControl97_PRNG_Reseed_t;
+
+// EIP-197 Debug statistics
+typedef EIP97_Global_Debug_Statistics_t GlobalControl97_Debug_Statistics_t;
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_DFE_Status_Get
+ *
+ * This function retrieves the global status information
+ * from the EIP-97 HIA DFE hardware.
+ *
+ * This function can detect the EIP-97 Fatal Error condition requiring
+ * the EIP-97 Global SW or HW Reset!
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * DFE_Status_p (output)
+ *     Pointer to the data structure where the DFE status will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_DFE_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_DFE_Status_t * const DFE_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_DSE_Status_Get
+ *
+ * This function can detect the EIP-97 Fatal Error condition requiring
+ * the EIP-97 Global SW or HW Reset!
+ *
+ * This function can detect the EIP-97 Fatal Error condition requiring
+ * the EIP-97 Global SW or HW Reset!
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * DSE_Status_p (output)
+ *     Pointer to the data structure where the DSE status will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_DSE_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_DSE_Status_t * const DSE_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Token_Status_Get
+ *
+ * This function retrieves the EIP-96 Token status information
+ * from the EIP-97 hardware (includes HIA DFE, HIA DSE and EIP-96 PE)
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * Token_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Token status
+ *     will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_Token_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Token_Status_t * const Token_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Context_Status_Get
+ *
+ * This function retrieves the EIP-96 Context status information
+ * from the EIP-97 hardware (includes HIA DFE, HIA DSE and EIP-96 PE)
+ *
+ * This function can detect the EIP-97 Fatal Error condition requiring
+ * the EIP-97 Global SW or HW Reset!
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * Context_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Context status
+ *     will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_Context_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Context_Status_t * const Context_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Interrupt_Status_Get
+ *
+ * This function retrieves the EIP-96 Interrupt status information
+ * from the EIP-97 hardware (includes HIA DFE, HIA DSE and EIP-96 PE)
+ *
+ * This function can detect the EIP-97 Fatal Error condition requiring
+ * the EIP-97 Global SW or HW Reset!
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * Interrupt_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Interrupt status
+ *     will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_Interrupt_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Interrupt_Status_t * const Interrupt_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_OutXfer_Status_Get
+ *
+ * This function retrieves the EIP-96 Output Transfer status information
+ * from the EIP-97 hardware (includes HIA DFE, HIA DSE and EIP-96 PE)
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * OutXfer_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 Output Transfer status
+ *     will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_OutXfer_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Output_Transfer_Status_t * const OutXfer_Status_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_PRNG_Status_Get
+ *
+ * This function retrieves the EIP-96 PRNG status information
+ * from the EIP-97 hardware (includes HIA DFE, HIA DSE and EIP-96 PE)
+ *
+ * PE_Number (input)
+ *     Number of the EIP-97 Processing Engine for which the status information
+ *     must be retrieved
+ *
+ * PRNG_Status_p (output)
+ *     Pointer to the data structure where the EIP-96 PRNG status
+ *     will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_PRNG_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_PRNG_Status_t * const PRNG_Status_p);
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_PRNG_Reseed
+ *
+ * This function performs the Packet Engine re-seed operation
+ *
+ * IOArea_p (input)
+ *     Pointer to the place holder in memory for the IO Area.
+ *
+ * PE_Number (input)
+ *     Number of the PE that must be re-seed.
+ *
+ * ReseedData_p (input)
+ *     Pointer to the PRNG seed and key data.
+ *
+ * This function is not re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : re-seed done successfully
+ *     GLOBAL_CONTROL_ERROR_INTERNAL : operation failed
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_PRNG_Reseed(
+        const unsigned int PE_Number,
+        const GlobalControl97_PRNG_Reseed_t * const ReseedData_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Debug_Statistics_Get
+ *
+ * This function retrieves the debug statistics
+ * from the EIP-197
+ *
+ * Debug_Statistics_p (output)
+ *     Pointer to the data structure where the debug statistics will be stored
+ *
+ * This function is re-entrant.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_NO_ERROR : status retrieved successfully
+ *     GLOBAL_CONTROL_ERROR_BAD_PARAMETER : invalid parameter
+ */
+GlobalControl97_Error_t
+GlobalControl97_Debug_Statistics_Get(
+        GlobalControl97_Debug_Statistics_t * const Debug_Statistics_p);
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Interfaces_Get
+ *
+ * Read the number of available packet interfaces.
+ *
+ * NofPEs_p (output)
+ *    Number of processing engines.
+ * NofRings_p (output)
+ *    Number of available ring pairs.
+ * NofLAInterfaces_p (output)
+ *    Number of available Look-Aside FIFO interfaces.
+ * NofInlineInterfaces_p (output)
+ *    Number of available Inline interfaces.
+ *
+ * If all returned values are zero, the device has not been initialized.
+ * This is considered an error.
+ */
+void
+GlobalControl97_Interfaces_Get(
+    unsigned int * const NofPEs_p,
+    unsigned int * const NofRings_p,
+    unsigned int * const NofLAInterfaces_p,
+    unsigned int * const NofInlineInterfaces_p);
+
+
+#endif /* API_GLOBAL_STATUS_EIP97_H_ */
+
+
+/* end of file api_global_status_eip97.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_memxs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_memxs.h
new file mode 100644
index 0000000..fc525f5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_memxs.h
@@ -0,0 +1,313 @@
+/* api_memxs.h
+ *
+ * Low-level Memory Access (MemXS) API
+ *
+ * This API should be used for debugging purposes only.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef API_MEMXS_H_
+#define API_MEMXS_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef enum
+{
+    MEMXS_STATUS_OK,              // Operation is successful
+    MEMXS_INVALID_PARAMETER,      // Invalid input parameter
+    MEMXS_UNSUPPORTED_FEATURE,    // Feature is not implemented
+    MEMXS_ERROR                   // Operation has failed
+} MemXS_Status_t;
+
+/*----------------------------------------------------------------------------
+ * MemXS_Handle_t
+ *
+ * This handle is a reference to a memory resource.
+ *
+ * The handle is set to NULL when MemXS_Handle_t handle.p is equal to NULL.
+ *
+ */
+typedef struct
+{
+    void * p;
+} MemXS_Handle_t;
+
+/*----------------------------------------------------------------------------
+ * MemXS_DevInfo_t
+ *
+ * Memory device data structure.
+ *
+ */
+typedef struct
+{
+    // Memory device handle
+    MemXS_Handle_t Handle;
+
+    // Device name (zero-terminated string)
+    const char * Name_p;
+
+    // Device index
+    unsigned int Index;
+
+    // Device start offset
+    unsigned int FirstOfs;
+
+    // Device end offset
+    unsigned int LastOfs;
+
+} MemXS_DevInfo_t;
+
+/*----------------------------------------------------------------------------
+ * MemXS_NULLHandle
+ *
+ * This handle can be assigned to a variable of type MemXS_Handle_t.
+ *
+ */
+extern const MemXS_Handle_t MemXS_NULLHandle;
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Init
+ *
+ * An application must call this API once prior to using any other API
+ * functions. During this call the service ensures that the Additional Address
+ * Space and Device are accessible for read/write operations.
+ *
+ * Return value:
+ *      true:  Initialization was successful, the other APIs can now be used.
+ *      false: Initialization failed, the other APIs cannot be used.
+ */
+bool
+MemXS_Init (void);
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Handle_IsSame
+ *
+ * Check whether provided Handle1 is equal to provided Handle2.
+ *
+ * Handle1_p
+ *      First handle
+ *
+ * Handle2_p
+ *      Second handle
+ *
+ * Return values
+ *      true:  provided handles are equal
+ *      false: provided handles are not equal
+ *
+ */
+bool
+MemXS_Handle_IsSame(
+        const MemXS_Handle_t * const Handle1_p,
+        const MemXS_Handle_t * const Handle2_p);
+
+
+/*-----------------------------------------------------------------------------
+ * MemXS_Device_Count_Get
+ *
+ * Returns the number of device which memory (MMIO, internal RAM) can be
+ * accessed via this API.
+ *
+ * DeviceCount_p (output)
+ *      Pointer to a memory location where the number of supported devices
+ *      will be stored.
+ *
+ * Return:
+ *     MEMXS_STATUS_OK
+ *     MEMXS_INVALID_PARAMETER
+ *     MEMXS_ERROR
+ */
+MemXS_Status_t
+MemXS_Device_Count_Get(
+        unsigned int * const DeviceCount_p);
+
+
+/*-----------------------------------------------------------------------------
+ * MemXS_Device_Info_Get
+ *
+ * Returns the data structure that describes the device identified by
+ * DeviceIndex parameter.
+ *
+ * DeviceIndex (input)
+ *      Device index, from 0 to the number obtained via
+ *      the MemXS_Device_Count_Get() function.
+ *
+ * DeviceInfo_p (output)
+ *      Pointer to a memory location where the number of supported devices
+ *      will be stored.
+ *
+ * Return:
+ *     MEMXS_STATUS_OK
+ *     MEMXS_INVALID_PARAMETER
+ *     MEMXS_ERROR
+ */
+MemXS_Status_t
+MemXS_Device_Info_Get(
+        const unsigned int DeviceIndex,
+        MemXS_DevInfo_t * const DeviceInfo_p);
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Read32
+ *
+ * This function can be used to read one static 32bit resource inside a device
+ * (typically a register or memory location). Since reading registers can have
+ * side effects, the implementation must guarantee that the resource will be
+ * read only once and no neighboring resources will be accessed.
+ *
+ * If required (decided based on internal configuration), on the fly endianness
+ * swapping of the value read will be performed before it is returned to the
+ * caller.
+ *
+ * Handle (input)
+ *     Handle for the device instance which memory must be read.
+ *
+ * ByteOffset (input)
+ *     The byte offset within the device for the resource to read.
+ *
+ * Return Value
+ *     The value read.
+ *
+ * When the Handle or Offset parameters are invalid, the implementation will
+ * return an unspecified value.
+ */
+uint32_t
+MemXS_Read32(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset);
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Write32
+ *
+ * This function can be used to write one static 32bit resource inside a
+ * device (typically a register or memory location). Since writing registers
+ * can have side effects, the implementation must guarantee that the resource
+ * will be written exactly once and no neighboring resources will be
+ * accessed.
+ *
+ * If required (decided based on internal configuration), on the fly endianness
+ * swapping of the value to be written will be performed.
+ *
+ * Handle (input)
+ *     Handle for the device instance which memory must be read.
+ *
+ * ByteOffset (input)
+ *     The byte offset within the device for the resource to write.
+ *
+ * Value (input)
+ *     The 32bit value to write.
+ *
+ * Return Value
+ *     None
+ *
+ * The write can only be successful when the Handle and ByteOffset parameters
+ * are valid.
+ */
+void
+MemXS_Write32(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const uint32_t Value);
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Read32Array
+ *
+ * This function perform the same task as MemXS_Read32 for an array of
+ * consecutive 32bit words, allowing the implementation to use a more optimal
+ * burst-read (if available).
+ *
+ * See MemXS_Read32 for pre-conditions and a more detailed description.
+ *
+ * Handle (input)
+ *     Handle for the device instance which memory must be read.
+ *
+ * StartByteOffset (input)
+ *     Byte offset of the first resource to read.
+ *     This value is incremented by 4 for each following resource.
+ *
+ * MemoryDst_p (output)
+ *     Pointer to the memory where the retrieved words will be stored.
+ *
+ * Count (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Return Value
+ *     None.
+ */
+void
+MemXS_Read32Array(
+        const MemXS_Handle_t Handle,
+        const unsigned int StartByteOffset,
+        uint32_t * MemoryDst_p,
+        const int Count);
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Write32Array
+ *
+ * This function perform the same task as MemXS_Write32 for an array of
+ * consecutive 32bit words, allowing the implementation to use a more optimal
+ * burst-write (if available).
+ *
+ * See MemXS_Write32 for pre-conditions and a more detailed description.
+ *
+ * Handle (input)
+ *     Handle for the device instance which memory must be read.
+ *
+ * StartByteOffset (input)
+ *     Byte offset of the first resource to write.
+ *     This value is incremented by 4 for each following resource.
+ *
+ * MemorySrc_p (input)
+ *     Pointer to the memory where the values to be written are located.
+ *
+ * Count (input)
+ *     The number of 32bit words to transfer.
+ *
+ * Return Value
+ *     None.
+ */
+void
+MemXS_Write32Array(
+        const MemXS_Handle_t Handle,
+        const unsigned int StartByteOffset,
+        const uint32_t * MemorySrc_p,
+        const int Count);
+
+
+#endif /* API_MEMXS_H_ */
+
+
+/* end of file api_memxs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl.h
new file mode 100644
index 0000000..8df6794
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl.h
@@ -0,0 +1,515 @@
+/* api_pcl.h
+ *
+ * Packet Classification API.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef API_PCL_H_
+#define API_PCL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+// Dependency on DMA Buffer Allocation API (api_dmabuf.h)
+#include "api_dmabuf.h"         // DMABuf_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+typedef enum
+{
+    PCL_STATUS_OK,              // Operation is successful
+    PCL_STATUS_BUSY,            // Device busy, try again later
+    PCL_INVALID_PARAMETER,      // Invalid input parameter
+    PCL_UNSUPPORTED_FEATURE,    // Feature is not implemented
+    PCL_OUT_OF_MEMORY_ERROR,    // Out of memory
+    PCL_ERROR                   // Operation has failed
+} PCL_Status_t;
+
+/* Flags for selector parameters */
+#define PCL_SELECT_IPV4     BIT_0   // Packet is IPv4.
+#define PCL_SELECT_IPV6     BIT_1   // Packet is IPv6.
+
+
+/*----------------------------------------------------------------------------
+ * PCL_SelectorParams_t
+ *
+ * This data structure represents the packet parameters (such as IP addresses
+ * and ports) that select a particular flow.
+ */
+typedef struct
+{
+    uint32_t flags;    // Bitwise or of zero or more PCL_SELECT_* flags.
+    uint8_t *SrcIp;    // IPv4 (4 bytes)source address.
+    uint8_t *DstIp;    // IPv4 (4 bytes)destination address.
+    uint8_t IpProto;   // IP protocol (UDP, ESP).
+    uint16_t SrcPort;  // Source port for UDP.
+    uint16_t DstPort;  // Destination port for UDP.
+    uint32_t spi;      // SPI in IPsec
+    uint16_t epoch;    // Epoch in DTLS.
+} PCL_SelectorParams_t;
+
+/* Flags for flow parameters */
+#define PCL_FLOW_INBOUND  BIT_1  // Flow is for inbound IPsec packets.
+#define PCL_FLOW_SLOWPATH BIT_2  // Packets should not be processed in hardware
+
+/*----------------------------------------------------------------------------
+ * PCL_FlowParams_t
+ *
+ * This data structure represents the flow data structure visible to the
+ * application. The actual flow record may contain additional information,
+ * such as the physical addresses of the transform record and links for the
+ * Flow Hash Table.
+ */
+typedef struct
+{
+    uint32_t FlowID[4];       // The 128-bit flow ID computed by the flow hash
+                              // function from the selector parameters.
+
+    uint32_t FlowIndex;       // Reference to flow table entry in application.
+                              // An Ipsec implementation may maintain a flow
+                              // table in software that contains more
+                              // information than is accessible to the
+                              // Classification Engine. FlowIndex may be
+                              // used by software to refer bo this software
+                              // flow record.
+
+    uint32_t flags;           // Bitwise of zero or more PCL_FLOW_* flags.
+    uint32_t SourceInterface; // Representation of the network interface
+
+    // Transform that is to be applied.
+    DMABuf_Handle_t transform;
+
+    // Time last accessed, in engine clock cycles.
+    uint32_t LastTimeLo;
+    uint32_t LastTimeHi;
+
+    // Number of packets processed by this flow.
+    uint32_t PacketsCounterLo;
+    uint32_t PacketsCounterHi;
+
+    // Number of octets processed by this flow.
+    uint32_t OctetsCounterLo;
+    uint32_t OctetsCounterHi;
+
+} PCL_FlowParams_t;
+
+/*----------------------------------------------------------------------------
+ * PCL_TransformParams_t
+ *
+ * This data structure represents parameters from the transform record
+ * that the application must be able to access after the transform
+ * record is created.
+ */
+typedef struct
+{
+    // 32-bit sequence number of outbound transform.
+    uint32_t SequenceNumber;
+
+    // Time last of transform record access, in engine clock cycles.
+    uint32_t LastTimeLo;
+    uint32_t LastTimeHi;
+
+    // Number of packets processed for this transform.
+    uint32_t PacketsCounterLo;
+    uint32_t PacketsCounterHi;
+
+    // Number of octets processed for this transform.
+    uint32_t OctetsCounterLo;
+    uint32_t OctetsCounterHi;
+
+} PCL_TransformParams_t;
+
+// Flow Record handle
+typedef void * PCL_FlowHandle_t;
+
+
+/*----------------------------------------------------------------------------
+ * PCL_Init
+ *
+ * Initialize the classification functionality. After the initialization no
+ * transform records are registered and no flow records exist. This function
+ * must be called before any other function of this API is called.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * NofFlowHashTables (input)
+ *     Number of the Flow Hash Tables to set up
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_UNSUPPORTED_FEATURE
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Init(
+        const unsigned int InterfaceId,
+        const unsigned int NofFlowHashTables);
+
+
+/*----------------------------------------------------------------------------
+ * PCL_UnInit
+ *
+ * Uninitialize the classification functionality. Before this
+ * function may be called, all the transform records must be unregistered and
+ * all the flow records must be destroyed.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_UnInit(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * PCL_Flow_DMABuf_Handle_Get
+ *
+ * Obtain DMABuf_Handle_t type handle from the provided PCL_FlowHandle_t type
+ * handle.
+ *
+ * FlowHandle (input)
+ *     Handle of the flow record.
+ *
+ * DMAHandle_p (output)
+ *     Pointer to the memory location where the handle representing
+ *     the allocated flow record as a DMA resource (see DMABuf API)
+ *     will be stored.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ */
+PCL_Status_t
+PCL_Flow_DMABuf_Handle_Get(
+        const PCL_FlowHandle_t FlowHandle,
+        DMABuf_Handle_t * const DMAHandle_p);
+
+
+/*----------------------------------------------------------------------------
+ * PCL_Flow_Hash
+ *
+ * Compute a 128-bit hash value from the provided selector parameters.
+ * This value can be assumed to be unique for every different
+ * combination of system parameters. The hash computation is the exact
+ * same computation that the classification hardware would do for a packet with
+ * the same parameters. Which fields are hashed, depends on the specified
+ * protocol (UDP will hash source and destination ports, ESP will hash SPI).
+ * This value is subsequently used to identify looked-up records.
+ *
+ * SelectorParams (input)
+ *     Set of packet parameters to select a particular flow.
+ *
+ * FlowID_Word32ArrayOf4 (output)
+ *     128-bit hash value that will be used to uniquely identify a looked-up
+ *     record. This must point to a buffer that can hold 4 32-bit words.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_UNSUPPORTED_FEATURE
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Hash(
+        const PCL_SelectorParams_t * const SelectorParams,
+        uint32_t * FlowID_Word32ArrayOf4);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Lookup
+ *
+ * Find a flow in the Flow Hash Table with a matching flow ID.
+ * If no such flow is found, return a null handle.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier that should be used for the flow record
+ *     lookup
+ *
+ * FlowID_Word32ArrayOf4 (input)
+ *     128-bit flow ID to find.
+ *
+ * FlowHandle_p (output)
+ *     Handle to access the flow record found, e.g. via PCL_Flow_Get_ReadOnly()
+ *     (or null handle of no flow found).
+ *
+ * Return:
+ *     PCL_STATUS_OK:           flow record is found
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR:               no flow record is found
+ */
+PCL_Status_t
+PCL_Flow_Lookup(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const uint32_t * FlowID_Word32ArrayOf4,
+        PCL_FlowHandle_t * const FlowHandle_p);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Alloc
+ *
+ * Allocate all dynamic storage resources for a flow record, but do not
+ * add a flow record to the table.
+ *
+ * Note:  This function will allocate a buffer to store the actual flow record
+ *        and all administration used by the driver (represented by FlowHandle).
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the flow record should be allocated
+ *
+ * FlowHandle_p (output)
+ *     Handle to represent the allocated flow record. This will be used
+ *     as an input parameter to other flow related functions in this API.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Alloc(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        PCL_FlowHandle_t * const FlowHandle_p);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Add
+ *
+ * Create a new flow record from the supplied parameters and add it to the
+ * Flow Hash Table. Its dynamic storage resources must already be allocated.
+ *
+ * Note:  This function will add a flow record to the flow table.
+ *        The FlowHandle must represent an allocated, but unused
+ *        flow record buffer.
+ *        No flow record may already exist with the same flow ID.
+ *        The application is responsible for this.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the flow record should be added
+ *
+ * FlowParams (input)
+ *     Contents of the flow that is to be added.
+ *
+ * FlowHandle (input)
+ *     Handle representing the storage space for the flow record
+ *     (as returned by PCL_Flow_Alloc). If this function returns with
+ *     PCL_STATUS_OK, the flow record will be in use and the handle can be
+ *     used with PCL_Flow_Remove() or PCL_Flow_Get_ReadOnly().
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Add(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowParams_t * const FlowParams,
+        const PCL_FlowHandle_t FlowHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Remove
+ *
+ * Remove the indicated flow record from the Flow Hash Table. If the
+ * flow record references a transform record then that transform
+ * record must be unregistered after the flow record is removed.
+ * The flow handle must represent a flow record that is currently in the
+ * Flow Hash Table (by PCL_Flow_Add).
+ *
+ * When this function returns, the dynamic storage resources of the flow
+ * record are still allocated and they can be reused by another call to
+ * PCL_Flow_Add() or the resources can be released by PCL_Flow_Release().
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the flow record should be removed
+ *
+ * FlowHandle (input)
+ *     Handle of the flow record to be removed.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowHandle_t FlowHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Release
+ *
+ * Release all dynamic storage resources of a flow record. The
+ * FlowHandle must represent an allocated, but unused flow record
+ * buffer.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the flow record was originally
+ *     allocated.
+ *
+ * FlowHandle (input)
+ *     Handle of the flow record to be released. When this function returns,
+ *     this handle us no longer a valid input to any of the flow related
+ *     API functions.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Release(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowHandle_t FlowHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Get_ReadOnly
+ *
+ * Read the contents of a flow record with no intent to update it.
+ *
+ * FlowHandle (input)
+ *     Handle of the flow record to be read.
+ *
+ * FlowParams_p (output)
+ *     Contents read from the flow record (storage space provided by
+ *     application).
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Flow_Get_ReadOnly(
+        const PCL_FlowHandle_t FlowHandle,
+        PCL_FlowParams_t * const FlowParams_p);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_Register
+ *
+ * Register the transform record. Flow records may only reference transform
+ * records that have been made registered with this function.
+ *
+ * Before this function is called, the application has already
+ * allocated a buffer through the DMABuf API and has already filled it
+ * with transform data, for example via using the SA Builder API.
+ *
+ * TransformDMAHandle (input)
+ *     DMABuf Handle of the transform to be added.
+ *
+ * Return:
+ *     PCL_STATUS_OK when operation was successful.
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Transform_Register(
+        const DMABuf_Handle_t XformDMAHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_UnRegister
+ *
+ * Unregister the transform. The buffer represented
+ * by XformDMAHandle remains allocated and the application is responsible
+ * for releasing it. The flow record must be removed before its transform
+ * record can be unregistered.
+ *
+ * Note: When this function is called, no flow records may reference
+ *       the unregistered transform record.
+ *
+ * XformDMAHandle (input)
+ *     DMABuf Handle of the transform to be removed.
+ *
+ * Return:
+ *     PCL_STATUS_OK when operation was successful.
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Transform_UnRegister(
+        const DMABuf_Handle_t XformDMAHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_Get_ReadOnly
+ *
+ * Read a subset of the contents of the transform record into a
+ * parameters structure.
+ *
+ * XformDMAHandle (input)
+ *     DMABuf Handle of the transform to be accessed.
+ *
+ * TransformParams_p (output)
+ *     Transform parameters read from the transform record.
+ *
+ * Return:
+ *     PCL_STATUS_OK
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_Transform_Get_ReadOnly(
+        const DMABuf_Handle_t XformDMAHandle,
+        PCL_TransformParams_t * const TransformParams_p);
+
+
+#endif /* API_PCL_H_ */
+
+
+/* end of file api_pcl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl_dtl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl_dtl.h
new file mode 100644
index 0000000..0ea21b8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pcl_dtl.h
@@ -0,0 +1,291 @@
+/* api_pcl_dtl.h
+ *
+ * Packet Classification API extensions for the Direct Transform Lookup (DTL).
+ *
+ * The PCL DTL API functions may be used only for those Transform
+ * Records which can be looked up directly by the Classification Engine
+ * in the Flow Hash Table (without using a Flow Record).
+ *
+ * A Transform Record for direct lookup must be allocated using
+ * the DMABuf API DMABuf_Alloc() function. In order to determine the required
+ * size of of the DMA-buffer the SA Builder API function SABuilder_GetSizes()
+ * can be used. The allocated DMA-safe buffer subsequently must be filled in
+ * with the transform data, for example by using the SA Builder API, namely
+ * the SABuilder_BuildSA() function. Finally the allocated and filled in
+ * Transform Record must be added to the Flow Hash Table by means of
+ * the PCL_DTL_Transform_Add() function.
+ *
+ * Several different hash values can reference the same transform record.
+ * When the PCL_DTL_Transform_Add() function adds a transform record to
+ * the Flow Hash Table it also adds a hash value and returns its hash handle.
+ * In order to add a new hash value for the same transform record
+ * the PCL_DTL_Transform_Add() function can be called again with another hash
+ * ID value in the input transform parameters. If successful then this function
+ * stores the hash handle in its output parameter for the hash ID added to
+ * the Flow Hash Table for the requested transform record. In order to remove
+ * the hash value from the the Flow Hash Table the PCL_DTL_Transform_Remove()
+ * function must be called using the hash handle obtained in the previous call
+ * to the PCL_DTL_Transform_Add() function. If the hash handle is set to NULL
+ * then the PCL_DTL_Transform_Remove() function will removed all the hash values
+ * associated with the requested transform record from the Flow Hash Table.
+ *
+ * When a Transform Record for direct lookup must be deleted then, first,
+ * the PCL_DTL_Transform_Remove() function must be used. Second, the PEC API
+ * PEC_Packet_Put() function must be called for the Transform Record entry
+ * invalidation in the Record Cache. Finally, in order to release the dynamic
+ * resource storage the DMABuf API DMABuf_Release() function must be used.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+#ifndef API_PCL_DTL_H_
+#define API_PCL_DTL_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+// Dependency on DMA Buffer Allocation API (api_dmabuf.h)
+#include "api_dmabuf.h"         // DMABuf_Handle_t
+
+// Main PCL API
+#include "api_pcl.h"            // PCL_Status_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * PCL_DTL_TransformParams_t
+ *
+ * This data structure contains extended transform parameters for the transform
+ * record that must be used for direct lookup.
+ */
+typedef struct
+{
+    // The 128-bit transform ID computed by the hash function
+    // from the selector parameters. This uniquely identifies the hash entry.
+    // One or multiple hash ID's (entries) can co-exist for the same transform.
+    // This can be calculated by the PCL_Flow_Hash() function.
+    uint32_t HashID[4];
+
+    // Reference to a generic transform parameters, set to NULL if not used
+    PCL_TransformParams_t * Params_p;
+
+} PCL_DTL_TransformParams_t;
+
+
+/*----------------------------------------------------------------------------
+ * PCL_DTL_Hash_Handle_t
+ *
+ * This handle is a reference to a hash ID in the Flow Hash Table.
+ *
+ * The handle is set to NULL when PCL_DTL_Hash_Handle_t handle.p is equal
+ * to NULL (or use HashHandle = PCL_DTL_NULLHandle).
+ *
+ */
+typedef struct
+{
+    void * p;
+} PCL_DTL_Hash_Handle_t;
+
+
+/*----------------------------------------------------------------------------
+ * PCL_DTL_NULLHandle
+ *
+ * This handle can be assigned to a variable of type PCL_DTL_Hash_Handle_t.
+ *
+ */
+extern const PCL_DTL_Hash_Handle_t PCL_DTL_NULLHandle;
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Init
+ *
+ * Initialize the PCL DTL functionality.
+ *
+ * API use order:
+ *     This function must be called before any other PCL DTL API functions
+ *     are called.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * Return (see PCL_Status_t in api_pcl.h):
+ *     PCL_STATUS_OK
+ *     PCL_STATUS_BUSY
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_DTL_Init(
+        const unsigned int InterfaceId);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_UnInit
+ *
+ * Uninitialize the PCL DTL functionality.
+ *
+ * API use order:
+ *     After this function is called none of the PCL DTL API functions
+ *     can be called called except the PCL_DTL_Init() function.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * Return (see PCL_Status_t in api_pcl.h):
+ *     PCL_STATUS_OK
+ *     PCL_STATUS_BUSY
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_DTL_UnInit(
+        const unsigned int InterfaceId);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Transform_Add
+ *
+ * Create a hash value (ID) for the provided Transform Record from
+ * the provided transform parameters and add it to the Flow Hash Table.
+ * One transform record may have multiple hash ID's associated with it. This
+ * function can be called several times to add different hash ID's for
+ * the same Transform Record in the Flow Hash Table.
+ *
+ * Note:  The same hash ID cannot be used for different Transform Records.
+ *
+ * Note:  This function will return PCL_INVALID_PARAMETER for the transform
+ *        parameters that were already successfully used to add a hash value
+ *        to the Flow Hash Table for this record in an previous call
+ *        to PCL_DTL_Transform_Add().
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the hash ID should be added
+ *
+ * TransformParams (input)
+ *     Contents of the hash ID that is to be added.
+ *
+ * XformDMAHandle (input)
+ *     Handle representing the Transform Record as returned by DMABuf_Alloc().
+ *     If this function returns with PCL_STATUS_OK, the new hash value
+ *     for this Transform Record will be in use.
+ *
+ * HashHandle_p (output)
+ *     Pointer to the memory location when the hash handle will be returned.
+ *
+ * Return (see PCL_Status_t in api_pcl.h):
+ *     PCL_STATUS_OK
+ *     PCL_STATUS_BUSY
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ *     PCL_OUT_OF_MEMORY_ERROR
+ */
+PCL_Status_t
+PCL_DTL_Transform_Add(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_DTL_TransformParams_t * const TransformParams,
+        const DMABuf_Handle_t XformDMAHandle,
+        PCL_DTL_Hash_Handle_t * const HashHandle_p);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Transform_Remove
+ *
+ * Remove all the hash ID's associated with the Transform Record,
+ * the dynamic storage resource represented by XformDMAHandle remains allocated
+ * and it can be reused by another call to PCL_DTL_Transform_Add().
+ * The application is responsible for releasing Transform Record buffer
+ * via the DMABuf_Release() function.
+ *
+ * The XformDMAHandle must represent a Transform Record that is currently
+ * in the Flow Hash Table (as added by the PCL_DTL_Transform_Add() function).
+ *
+ * Note:  This function will return PCL_INVALID_PARAMETER for the transform
+ *        record that has no more hash ID's in the Flow Hash Table associated
+ *        with it.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the Transform Record should be removed
+ *
+ * XformDMAHandle (input)
+ *     Handle of the Transform Record to be removed
+ *
+ * Return (see PCL_Status_t in api_pcl.h):
+ *     PCL_STATUS_OK
+ *     PCL_STATUS_BUSY
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_DTL_Transform_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const DMABuf_Handle_t XformDMAHandle);
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Hash_Remove
+ *
+ * Remove the hash ID referenced by the HashHandle from the Flow Hash Table.
+ *
+ * The HashHandle must reference the hash ID that is currently
+ * in the Flow Hash Table (as returned by the PCL_DTL_Transform_Add()
+ * function) for the specified Transform Record handle.
+ *
+ * InterfaceId (input)
+ *     Identifier of the Classification Engine interface
+ *
+ * FlowHashTableId (input)
+ *     Flow Hash Table identifier where the Transform Record should be removed
+ *
+ * HashHandle (input/output)
+ *     Handle for the hash ID to be removed
+ *
+ * Return (see PCL_Status_t in api_pcl.h):
+ *     PCL_STATUS_OK
+ *     PCL_STATUS_BUSY
+ *     PCL_INVALID_PARAMETER
+ *     PCL_ERROR
+ */
+PCL_Status_t
+PCL_DTL_Hash_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        PCL_DTL_Hash_Handle_t * const HashHandle_p);
+
+
+#endif /* API_PCL_DTL_H_ */
+
+
+/* end of file api_pcl_dtl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec.h
new file mode 100644
index 0000000..a705b56
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec.h
@@ -0,0 +1,751 @@
+/* api_pec.h
+ *
+ * Packet Engine Control API (PEC)
+ *
+ * This API can be used to perform transforms on security protocol packets
+ * for a set of security network protocols like IPSec, MACSec, sRTP, SSL,
+ * DTLS, etc.
+ *
+ * This API can supports both Look-Aside (LA) and Hybrid (HB) use cases.
+ *
+ * Please note that this is a generic API that can be used for many transform
+ * engines. A separate document will detail the exact fields and parameters
+ * required for the SA and Descriptors.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_API_PEC_H
+#define INCLUDE_GUARD_API_PEC_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+// This API requires the use of the DMA Buffer Allocation API. All buffers
+// are passed through this API as handles.
+#include "api_dmabuf.h"         // DMABuf_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Error/status codes
+typedef enum
+{
+    PEC_STATUS_OK = 0,
+    PEC_STATUS_BUSY,            // Device busy, try again later
+    PEC_ERROR_BAD_PARAMETER,
+    PEC_ERROR_BAD_HANDLE,
+    PEC_ERROR_BAD_USE_ORDER,
+    PEC_ERROR_INTERNAL,
+    PEC_ERROR_NOT_IMPLEMENTED
+
+} PEC_Status_t;
+
+
+/*----------------------------------------------------------------------------
+ * PEC_InitBlock_t
+ *
+ * This structure contains service initialization parameters that are passed
+ * to the PEC_Init call.
+ *
+ * For forward-compatibility with future extensions, please zero-init the
+ * data structure before setting the fields and providing it to PEC_Init.
+ * Example: PEC_InitBlock_t InitBlock = {0};
+ */
+typedef struct
+{
+    bool fUseDynamicSA;             // true = use variable-size SA format
+
+    // the following fields are related to Scatter/Gather
+    // not all engines support this
+    unsigned int FixedScatterFragSizeInBytes;
+
+    bool fContinuousScatter; // Enable Continous Scatter Mode.
+} PEC_InitBlock_t;
+
+
+/*----------------------------------------------------------------------------
+ * PEC_CommandDescriptor_t
+ *
+ * This data structure describes a transform request that will be queued up
+ * for processing by the transform engine. It refers to the input and output
+ * data buffers, the SA buffer(s) and contains parameters that describe the
+ * transform, like the length of the data.
+ *
+ * For operations that do not require output buffers such as hash operations
+ * the SrcPkt_Handle and DstPkt_Handle parameters in the
+ * PEC_CommandDescriptor_t descriptor must be set equal by applications.
+ *
+ */
+typedef struct
+{
+    // the pointer that will be returned in the related result descriptor
+    void * User_p;
+
+    // Optional EIP-96 Instruction Token buffer,
+    // some packet engines do not use tokens,
+    // DMABuf_NULLHandle can be assigned to this variable when not used
+    DMABuf_Handle_t Token_Handle;
+
+    // EIP-96 Instruction Token size (in 32-bit words)
+    unsigned int Token_WordCount;
+
+    // data buffers
+    DMABuf_Handle_t SrcPkt_Handle;
+    DMABuf_Handle_t DstPkt_Handle;
+    unsigned int SrcPkt_ByteCount;
+    unsigned int Bypass_WordCount;
+
+    // SA reference
+    uint32_t SA_WordCount;
+    DMABuf_Handle_t SA_Handle1;
+    DMABuf_Handle_t SA_Handle2;
+
+    // Engine specific control fields
+    // with Transform specific values
+    uint32_t Control1;
+    uint32_t Control2;
+
+    // Input Token buffer with fixed size (determined by use case)
+    // This buffer must be allocated before the descriptor can be passed
+    // to PEC_Packet_Put()
+    uint32_t * InputToken_p;
+
+} PEC_CommandDescriptor_t;
+
+/*----------------------------------------------------------------------------
+ * PEC_ResultDescriptor_t
+ *
+ * This data structure contains the result of the transform request. The user
+ * can match the result to a command using the User_p field.
+ *
+ * A number of parameters from the command descriptor are also returned, as a
+ * courtesy service.
+ */
+typedef struct
+{
+    // the pointer that from the related command descriptor
+    void * User_p;
+
+    // data buffers
+    DMABuf_Handle_t SrcPkt_Handle;
+    DMABuf_Handle_t DstPkt_Handle;
+    uint32_t DstPkt_ByteCount;
+    void * DstPkt_p;
+    // Number of scatter particles used (continous scatter).
+    uint32_t NumParticles;
+
+    unsigned int Bypass_WordCount;
+
+    // Engine specific status fields
+    // with Transform specific values
+    uint32_t Status1;
+    uint32_t Status2;
+
+    // Output Token buffer with fixed size (determined by use case)
+    // This buffer must be allocated before the descriptor can be passed
+    // to PEC_Packet_Get()
+    uint32_t * OutputToken_p;
+
+} PEC_ResultDescriptor_t;
+
+
+// Per-packet flags
+#define PEC_PKT_FLAG_INIT_ARC4     BIT_0
+#define PEC_PKT_FLAG_HASH_FINAL    BIT_1
+
+
+/*----------------------------------------------------------------------------
+ * PEC_PacketParams_t
+ *
+ * This data structure contains the per-packet parameters in a
+ * device-independent way.
+ */
+typedef struct
+{
+    // Bitwise or of zero or more PEC_PKT_FLAG_* values, 0 if none apply.
+    uint8_t flags;
+
+    // Next header byte (IPsec padding) or pad byte value.
+    uint8_t PadByte;
+
+    // Blocksize to which the packet must be padded (must be power of 2).
+    uint16_t PadBoundary;
+
+    // Offset of ESP header
+    uint8_t Offset;
+
+    // Token Header Word.
+    uint32_t TokenHeaderWord;
+
+    // Hardware operation.
+    uint8_t HW_Services;
+
+} PEC_PacketParams_t;
+
+// Error status bits.
+#define PEC_PKT_ERROR_AUTH         BIT_0 // Authentication failure
+#define PEC_PKT_ERROR_PAD          BIT_1 // Pad verify fail
+#define PEC_PKT_ERROR_SEQNUM       BIT_2 // Sequence number check failure
+#define PEC_PKT_ERROR_BADCMD       BIT_3 // Invalid command.
+#define PEC_PKT_ERROR_BADALGO      BIT_4 // Invalid algorithm
+#define PEC_PKT_ERROR_PROHIBITED   BIT_5 // Prohibited algorithm
+#define PEC_PKT_ERROR_ZEROLENGTH   BIT_6 // Zero packet length
+#define PEC_PKT_ERROR_BADIP        BIT_7 // Invalid IP header
+#define PEC_PKT_ERROR_SPI          BIT_8 // SPI mismatch.
+#define PEC_PKT_ERROR_CRYPTBLKSIZE BIT_9 // Block size error
+#define PEC_PKT_ERROR_BADCOMBO     BIT_10 // Invalid combination of algorithms
+#define PEC_PKT_ERROR_LENGTH       BIT_11 // Length error
+#define PEC_PKT_ERROR_PROC         BIT_12 // Processing error
+#define PEC_PKT_ERROR_INBOUNDLEN   BIT_13 // Bad Inbound PE length
+#define PEC_PKT_ERROR_SYSBUS       BIT_14 // System bus error
+#define PEC_PKT_ERROR_DESCRIPTOR   BIT_15 // Command descriptor error
+#define PEC_PKT_ERROR_HASHBLKSIZE  BIT_16 // Hash block size error
+#define PEC_PKT_ERROR_TOKEN        BIT_17 // Error in token
+#define PEC_PKT_ERROR_BYPASS       BIT_18 // Too much bypass data
+#define PEC_PKT_ERROR_HASHOVF      BIT_19 // Hash input overflow
+#define PEC_PKT_ERROR_TTLHOP       BIT_20 // TTL/Hop limit underflow
+#define PEC_PKT_ERROR_CHKSUM       BIT_21 // Checksum error
+#define PEC_PKT_ERROR_TIMEOUT      BIT_22 // Packet engine timeout
+#define PEC_PKT_ERROR_DSCR_OVF     BIT_25 // Result descriptor overflow
+#define PEC_PKT_ERROR_BUF_OVF      BIT_26 // Result buffer overflow
+
+
+/*----------------------------------------------------------------------------
+ * PEC_ResultStatus_t
+ *
+ * This data structure contains the per-packet status/result in a
+ * device-independent way.
+ */
+typedef struct
+{
+    // Bitwise or of PEC_PKT_ERROR_* values. Zero for successful operation.
+    uint32_t errors;
+
+    // Number of pad bytes detected by packet operation.
+    uint8_t PadByteCount;
+
+    // Next header byte detected by inbound IPsec operation.
+    uint8_t NextHeader;
+
+    // Hybrid use case only: Type of Service (IPv4) / Traffic class (IPv6)
+    uint8_t TOS_TC;
+
+    // IPv4 Hybrid use case only:
+    // True if fragmentation is prohibited for the packet
+    bool fDF;
+
+    // IPv6 Hybrid use case only: Next Header field offset within packet header
+    uint16_t NextHeaderOffset;
+
+    // Hybrid use case only: Header Processing Context reference
+    uint32_t HdrProcCtxRef;
+
+} PEC_ResultStatus_t;
+
+/*----------------------------------------------------------------------------
+ * PEC_NotifyFunction_t
+ *
+ * This type specifies the callback function prototype for the function
+ * PEC_CommandNotify_Request and PEC_ResultNotify_Request.
+ * The notification will occur only once.
+ *
+ * NOTE: The exact context in which the callback function is invoked and the
+ *       allowed actions in that callback are implementation specific. The
+ *       intention is that all API functions can be used, except PEC_UnInit.
+ */
+typedef void (* PEC_NotifyFunction_t)(void);
+
+// Supported cryptographic algorthms and functions.
+#define PEC_SUPPORTED_OCE      BIT_1  // Output classification engine.
+#define PEC_SUPPORTED_ICE      BIT_2  // Input classification engine.
+#define PEC_SUPPORTED_FRC      BIT_3  // Flow record cache.
+#define PEC_SUPPORTED_MASK1024 BIT_4  // Anti-replay mask size 1024
+#define PEC_SUPPORTED_BC0      BIT_5  // External block cipher
+#define PEC_SUPPORTED_SM4      BIT_6
+#define PEC_SUPPORTED_SM3      BIT_7
+#define PEC_SUPPORTED_CHACHA20 BIT_8
+#define PEC_SUPPORTED_POLY1305 BIT_9
+#define PEC_SUPPORTED_MASK256  BIT_10  // Anti-replay mask size 256
+#define PEC_SUPPORTED_MASK384  BIT_11  // Anti-replay mask size 384
+#define PEC_SUPPORTED_AES      BIT_12  // AES modes ECB, CBC, CTR
+#define PEC_SUPPORTED_AES_FB   BIT_13  // CFB and OFB modes for AES
+#define PEC_SUPPORTED_DES      BIT_15  // DES/3DES modes ECB, CBC
+#define PEC_SUPPORTED_DES_FB   BIT_16  // CFB and OFB modes for DES/3DES
+#define PEC_SUPPORTED_ARC4     (BIT_19|BIT_18)
+#define PEC_SUPPORTED_AES_XTS  BIT_20
+#define PEC_SUPPORTED_WIRELESS BIT_21  // Kasumi, SNOW and ZUC algorithms
+#define PEC_SUPPORTED_MD5      BIT_22
+#define PEC_SUPPORTED_SHA1     BIT_23
+#define PEC_SUPPORTED_SHA2_256 BIT_25  // SHA2-224 and SHA2-256
+#define PEC_SUPPORTED_SHA2_512 BIT_26  // SHA2-384 and SHA2-512
+#define PEC_SUPPORTED_CBCMAC   BIT_27  // (X)CBC-MAC, 128-bit keys
+#define PEC_SUPPORTED_CBCMAC256 BIT_29 // CBC-MAC, 192 and 256 bit keys
+#define PEC_SUPPORTED_GHASH    BIT_30  // AES-GCM/GMAC
+#define PEC_SUPPORTED_SHA3     BIT_31
+
+/*----------------------------------------------------------------------------
+ * PEC_Capabilities_t
+ *
+ * szTextDescription[]
+ *     Zero-terminated descriptive text of the available services.
+ */
+#define PEC_MAXLEN_TEXT  128
+
+typedef struct
+{
+    char szTextDescription[PEC_MAXLEN_TEXT];
+    unsigned int SupportedFuncs;
+} PEC_Capabilities_t;
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Capabilities_Get
+ *
+ * This routine returns a structure that describes the capabilities of the
+ * implementation. See description of PEC_Capabilities_t for details.
+ *
+ * Capabilities_p
+ *     Pointer to the capabilities structure to fill in.
+ *
+ * This function is re-entrant.
+ */
+PEC_Status_t
+PEC_Capabilities_Get(
+        PEC_Capabilities_t * const Capabilities_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Init
+ *
+ * This function must be used to initialize the service. No API function may
+ * be used before this function has returned.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) to be initialized.
+ *
+ * InitBlock_p (input)
+ *     Pointer to the initialization block data
+ *
+ */
+PEC_Status_t
+PEC_Init(
+        const unsigned int InterfaceId,
+        const PEC_InitBlock_t * const InitBlock_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_UnInit
+ *
+ * This call un-initializes the service. Use only when there are no pending
+ * transforms. The caller must make sure that no API function is used while or
+ * after this function executes.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) to be un-initialized.
+ *
+ */
+PEC_Status_t
+PEC_UnInit(
+        const unsigned int InterfaceId);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SA_Register
+ *
+ * This function must be used to register an SA so it can be used for
+ * transforms. The caller is responsible for filling in the SA fields
+ * according to the specification of the engine, with the exception of any
+ * fields that are designated to hold addresses of the other SA memory blocks.
+ * The buffers are considered arrays of 32bit words in host-native byte order.
+ *
+ * When this call returns it is no longer allowed to access these SA memory
+ * blocks directly.
+ *
+ * InterfaceId (input)
+ *     Not used, reserved.
+ *
+ * SA_Handle1 (input)
+ *     Handle for the main SA memory block. This memory block contains all the
+ *     static material and is typically read completely for every transform
+ *     but only selective parts are written back after the transform.
+ *
+ * SA_Handle2 (input)
+ * SA_Handle3 (input)
+ *     Handles for the optional second and third memory blocks. These are
+ *     typically used to remember state information and are therefore
+ *     required only for certain types of SA's. These blocks are typically
+ *     read and written for every transform. Putting them in a separate memory
+ *     blocks allows these to be put in more high performance memory.
+ *     Provide zero for unused handles.
+ *
+ * The exact number of handles required depends on the transform engine and on
+ * the SA parameters and is specified in a separate document. The exact size
+ * of each memory block is known to the service through the handle.
+ */
+PEC_Status_t
+PEC_SA_Register(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t SA_Handle1,
+        DMABuf_Handle_t SA_Handle2,
+        DMABuf_Handle_t SA_Handle3);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SA_UnRegister
+ *
+ * This function must be used to remove an SA from the system, which means it
+ * can no longer be used to perform transforms with the engine. When this
+ * function returns the caller is allowed to access the SA memory blocks again.
+ *
+ * InterfaceId (input)
+ *     Not used, reserved.
+ *
+ * SA_Handle1 (input)
+ * SA_Handle2 (input)
+ * SA_Handle3 (input)
+ *     The same handles as we provided in the PEC_SA_Register call.
+ *     Provide zero for unused handles.
+ */
+PEC_Status_t
+PEC_SA_UnRegister(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t SA_Handle1,
+        DMABuf_Handle_t SA_Handle2,
+        DMABuf_Handle_t SA_Handle3);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Packet_Put
+ *
+ * This function must be put transform requests into a queue. It is possible
+ * to queue up just one request, or an array of requests (these do not have to
+ * be related). In case the queue is full, none or only a few of the requests
+ * might be queued up.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) where the packet(s)
+ *     must be submitted to. See the SLAD PEC API Implementation Notes
+ *     for the details on how this parameter is used.
+ *
+ * Commands_p (input)
+ *     Pointer to one (or an array of command descriptors, each describe one
+ *     transform request.
+ *
+ * CommandsCount (input)
+ *     The number of command descriptors pointed to by Commands_p.
+ *
+ * PutCount_p (output)
+ *     This parameter is used to return the actual number of descriptors that
+ *     was queued up for processing (0..CommandsCount).
+ */
+PEC_Status_t
+PEC_Packet_Put(
+        const unsigned int InterfaceId,
+        const PEC_CommandDescriptor_t * Commands_p,
+        const unsigned int CommandsCount,
+        unsigned int * const PutCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Packet_Get
+ *
+ * This function must be used to retrieve the results for the requested
+ * transform operations. Every request generates one result, whether it is
+ * successful or failed. The caller is able to retrieve one result or an
+ * array of results.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) where the packet(s)
+ *     must be retrieved from. See the SLAD PEC API Implementation Notes
+ *     for the details on how this parameter is used.
+ *
+ * Results_p (input)
+ *     Pointer to the result descriptor, or array of result descriptors, that
+ *     will be populated by the service based on completed transform requests.
+ *
+ * ResultsLimit (input)
+ *     The number of result descriptors available from Results_p and onwards.
+ *
+ * GetCount_p (output)
+ *     The actual number of result descriptors that were populated is returned
+ *     in this parameter.
+ */
+PEC_Status_t
+PEC_Packet_Get(
+        const unsigned int InterfaceId,
+        PEC_ResultDescriptor_t * Results_p,
+        const unsigned int ResultsLimit,
+        unsigned int * const GetCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_CommandNotify_Request
+ *
+ * This routine can be used to request a one-time notification of space
+ * available for new commands. It is typically used after PEC_PacketPut
+ * returned fewer packets added that requested (could be zero) and the caller
+ * does not want to poll for new results.
+ *
+ * Once the requested number of spaces are available, the implementation will
+ * invoke the callback one time to notify the user of the available results.
+ * The notification is then immediately disabled.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) for which notification
+ *     must be generated.
+ *
+ * CBFunc_p
+ *     Address of the callback function.
+ *
+ * CommandsCount
+ *     The number of commands that must be possible to add with
+ *     PEC_PacketPut before the notification function will be invoked.
+ */
+PEC_Status_t
+PEC_CommandNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int CommandsCount);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_ResultNotify_Request
+ *
+ * This routine can be used to request a one-time notification of available
+ * results. It is typically used after PEC_PacketGet returned zero results
+ * and the caller does not want to poll for new results.
+ *
+ * Once the requested transforms have completed, the implementation will
+ * invoke the callback one time to notify this fact.
+ * The notification is then immediately disabled. It is possible that the
+ * notification callback is invoked when fewer than the expected number of
+ * transforms have completed (or even zero). In this case the application
+ * must invoke PEC_ResultNotify_Request again to be notified of the completion
+ * of the remaining expected transforms.
+ *
+ * Once the notification callback is invoked, the application must use
+ * PEC_Packet_Get to read all available results and then call
+ * PEC_ResultNotifyRequest again, else the notification
+ * callback may not be called again.
+ *
+ * It is permissible (and even recommended) that the callback function
+ * calls PEC_Packet_Get to retrieve all available results and then
+ * PEC_ResultNotifyRequest to schedule the next invocation of the same
+ * callback. In this case the main application must call
+ * PEC_ResultNotify_Request exactly once after PEC_Init.
+ *
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) for which notification
+ *     must be generated.
+ *
+ * CBFunc_p
+ *     Address of the callback function.
+ *
+ * ResultsCount
+ *     The requested number of results that should be available the next
+ *     time PEC_Packet_Get is called after the callback function has occured.
+ *     This parameter should have a minimum value of 1 and its maximum value is
+ *     implementation dependend.
+ */
+PEC_Status_t
+PEC_ResultNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int ResultsCount);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_CD_Control_Write
+ *
+ * Write the Control1 and Control2 engine-specific fields in the
+ * Command Descriptor The other fields (such as SrcPkt_ByteCount and
+ * Bypass_WordCount must have been filled in already.
+ *
+ * Command_p (input, output)
+ *     Command descriptor whose Control1 and Control2 fields must be filled in.
+ *
+ * PacketParams_p (input)
+ *     Per-packet parameters.
+ *
+ * This function is not implemented for all engine types.
+ */
+PEC_Status_t
+PEC_CD_Control_Write(
+        PEC_CommandDescriptor_t * Command_p,
+        const PEC_PacketParams_t * const PacketParams_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_RD_Status_Read
+ *
+ * Read the engine-specific Status1 and Status2 fields from a Result Descriptor
+ * and convert them to an engine-independent format.
+ *
+ * Result_p (input)
+ *     Result descriptor.
+ *
+ * ResultStatus_p (output)
+ *     Engine-independent status information.
+ *
+ * Not all error conditions can occur on all engine types.
+ */
+PEC_Status_t
+PEC_RD_Status_Read(
+        const PEC_ResultDescriptor_t * const Result_p,
+        PEC_ResultStatus_t * const ResultStatus_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Scatter_Preload
+ *
+ * This function must be used to pre-load the service with scatter buffers
+ * that will be consumed by transforms configured to use scatter buffers
+ * instead of a provided destination buffer(s). This is required for certain
+ * engines only - check the driver documentation.
+ *
+ * InterfaceId (input)
+ *    Packet I/O interface (such as ring, for example) for which scatter buffers
+ *    must be pre-loaded.
+ *
+ * Handles_p (input)
+ *     Pointer to an array of handles, each handle representing one scatter
+ *     buffer.
+ *
+ * HandlesCount (input)
+ *     The number of handles in the array pointed to by Handles_p.
+ *
+ * AcceptedCount_p (output)
+ *     Pointer to the output parameter that reports how many of the handles,
+ *     from the start of the array, could accepted by the service due to
+ *     storage capacity limit. Value will be between 0 and HandlesCount.
+ */
+PEC_Status_t
+PEC_Scatter_Preload(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t * Handles_p,
+        const unsigned int HandlesCount,
+        unsigned int * const AcceptedCount_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Scatter_PreloadNotify_Request
+ *
+ * This routine can be used to request a one-time notification of space
+ * available in the scatter preload list. This is typically used when
+ * PEC_Scatter_Preload does not accept further buffers and the caller
+ * does not want to keep making those calls.
+ *
+ * Once the requested number of scatter buffers have been consumed, the
+ * implementation will invoke the callback one time to notify this fact.
+ * The notification is then immediately disabled.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) for which notification
+ *     must be generated.
+ *
+ * CBFunc_p
+ *     Address of the callback function.
+ *
+ * ConsumedCount
+ *     The number of scatter buffers consumed before invoking the callback.
+ */
+PEC_Status_t
+PEC_Scatter_PreloadNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int ConsumedCount);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Put_Dump
+ *
+ * Dump packet put operation administration and cache data.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) for which notification
+ *     must be generated.
+ *
+ * FirstSlotId (input)
+ *     First slot in the input ring buffer to start dumping.
+ *
+ * LastSlotId (input)
+ *     Last slot in the input ring buffer to stop dumping.
+ *
+ * fDumpPutAdmin (input)
+ *     true if the input ring administration data must be dumped.
+ *
+ * fDumpPutCache (input)
+ *     true if the input ring cache data must be dumped.
+ *
+ * Return value
+ *     None
+ */
+void
+PEC_Put_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpPutAdmin,
+        const bool fDumpPutCache);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Get_Dump
+ *
+ * Dump packet get operation administration and cache data.
+ *
+ * InterfaceId (input)
+ *     Packet I/O interface (such as ring, for example) for which notification
+ *     must be generated.
+ *
+ * FirstSlotId (input)
+ *     First slot in the output ring buffer to start dumping.
+ *
+ * LastSlotId (input)
+ *     Last slot in the output ring buffer to stop dumping.
+ *
+ * fDumpGetAdmin (input)
+ *     true if the output ring administration data must be dumped.
+ *
+ * fDumpGetCache (input)
+ *     true if the output ring cache data must be dumped.
+ *
+ * Return value
+ *     None
+ */
+void
+PEC_Get_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpGetAdmin,
+        const bool fDumpGetCache);
+
+
+#endif /* Include Guard */
+
+
+/* end of file api_pec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec_sg.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec_sg.h
new file mode 100644
index 0000000..ee53b69
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/api_pec_sg.h
@@ -0,0 +1,160 @@
+/* api_pec_sg.h
+ *
+ * Packet Engine Control API (PEC)
+ * Extension for Scatter/Gather (fragmented packet buffers)
+ *
+ * This API can be used to perform transforms on security protocol packets
+ * for a set of security network protocols like IPSec, MACSec, sRTP, SSL,
+ * DTLS, etc.
+ *
+ * Please note that this is a generic API that can be used for many transform
+ * engines. A separate document will detail the exact fields and parameters
+ * required for the SA and Descriptors.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_API_PEC_SG_H
+#define INCLUDE_GUARD_API_PEC_SG_H
+
+#include "basic_defs.h"
+#include "api_dmabuf.h"         // DMABuf_Handle_t
+#include "api_pec.h"            // PEC_Status_t
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Create
+ *
+ * This function must be used to create a list that can hold references to
+ * packet buffer fragments. The returned handle can be used in PEC_Packet_Put
+ * instead of a normal (contiguous) buffers.
+ *
+ * ListCapacity (input)
+ *     The number of scatter and/or gather fragments that this list can hold.
+ *
+ * SGList_Handle_p (output)
+ *     Pointer to the output parameter that will be filled in with the handle
+ *     that represents the newly created SGList.
+ */
+PEC_Status_t
+PEC_SGList_Create(
+        const unsigned int ListCapacity,
+        DMABuf_Handle_t * const SGList_Handle_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Destroy
+ *
+ * This function must be used to destroy a SGList that was previously created
+ * with PEC_SGList_Create. The potentially referred fragments in the list are
+ * not freed by the implementation!
+ *
+ * SGList_Handle (input)
+ *     The handle to the SGList as returned by PEC_SGList_Create.
+ */
+PEC_Status_t
+PEC_SGList_Destroy(
+        DMABuf_Handle_t SGList_Handle);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Write
+ *
+ * This function can be used to write a specific entry in the SGList with a
+ * packet fragment buffer information (handle, bytes used)
+ *
+ * SGList_Handle (input)
+ *     The handle to the SGList as returned by PEC_SGList_Create.
+ *
+ * Index (input)
+ *     Position in the SGList to write. This value must be in the range from
+ *     0..ListCapacity-1.
+ *
+ * FragmentHandle (input)
+ *     Handle for the fragment buffer.
+ *
+ * FragmentByteCount (input)
+ *     Number of bytes used in this fragment. Only used for gather.
+ */
+PEC_Status_t
+PEC_SGList_Write(
+        DMABuf_Handle_t SGList_Handle,
+        const unsigned int Index,
+        DMABuf_Handle_t FragmentHandle,
+        const unsigned int FragmentByteCount);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Read
+ *
+ * This function can be used to read one entry in the SGList. The function
+ * returns the handle together with the host address and size of the buffer.
+ *
+ * SGList_Handle (input)
+ *     The handle to the SGList as returned by PEC_SGList_Create.
+ *
+ * Index (input)
+ *     Position in the SGList to write. This value must be in the range from
+ *     0..ListCapacity-1.
+ *
+ * FragmentHandle_p (output)
+ *     Pointer to the output parameter that will receive the DMABuf handle
+ *     stored in this position of the list.
+ *     This parameter is optional and may be set to NULL.
+ *
+ * FragmentSizeInBytes_p (output)
+ *     Pointer to the output parameter that will receive the size of the
+ *     buffer represented by the FragmentHandle.
+ *     This parameter is optional and may be set to NULL.
+ *
+ * FragmentPtr_p (output)
+ *     Pointer to the output parameter (of type uint8_t *) that will receive
+ *     the address to the start of th ebuffer represented by FragmentHandle.
+ *     This parameter is optional and may be set to NULL.
+ */
+PEC_Status_t
+PEC_SGList_Read(
+        DMABuf_Handle_t SGList_Handle,
+        const unsigned int Index,
+        DMABuf_Handle_t * const FragmentHandle_p,
+        unsigned int * const FragmentSizeInBytes_p,
+        uint8_t ** const FragmentPtr_p);
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_GetCapacity
+ *
+ * This helper function can be used to retrieve the capacity of an SGList,
+ * so the caller does not have to remember this.
+ *
+ * SGList_Handle (input)
+ *     The handle to the SGList as returned by PEC_SGList_Create.
+ *
+ * ListCapacity_p (output)
+ *     Pointer to the output variable that will receive the capacity of the
+ *     SGList, assumingn SGList_Handle is valid.
+ */
+PEC_Status_t
+PEC_SGList_GetCapacity(
+        DMABuf_Handle_t SGList_Handle,
+        unsigned int * const ListCapacity_p);
+
+
+#endif /* Include Guard */
+
+/* end of file api_pec_sg.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs.h
new file mode 100644
index 0000000..f7f46fa
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs.h
@@ -0,0 +1,153 @@
+/* c_adapter_cs.h
+ *
+ * Default Global Classification Control Adapter configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_H
+#define INCLUDE_GUARD_C_ADAPTER_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Global Classification Control Adapter configuration
+#include "cs_adapter.h"
+
+
+/****************************************************************************
+ * Global Classification Control Adapter general configuration parameters
+ */
+
+#ifndef ADAPTER_CS_IV
+// Four words to provide IVs
+#define ADAPTER_CS_IV         {0x28e1d20f, 0x30507ca5, 0x084484f1, 0xb8a5aeab}
+#endif
+
+#ifndef ADAPTER_CS_TIMER_PRESCALER
+#define ADAPTER_CS_TIMER_PRESCALER           32
+#endif // ADAPTER_CS_TIMER_PRESCALER
+
+#ifndef ADAPTER_CS_RC_BLOCK_CLOCK_COUNT
+#define ADAPTER_CS_RC_BLOCK_CLOCK_COUNT      1
+#endif // ADAPTER_CS_RC_BLOCK_CLOCK_COUNT
+
+#ifndef ADAPTER_CS_FLUE_CACHE_CHAIN
+#define ADAPTER_CS_FLUE_CACHE_CHAIN          0
+#endif // ADAPTER_CS_FLUE_CACHE_CHAIN
+
+#ifndef ADAPTER_CS_FLUE_MEMXS_DELAY
+#define ADAPTER_CS_FLUE_MEMXS_DELAY          0
+#endif // ADAPTER_CS_FLUE_MEMXS_DELAY
+
+// Set to 0 to disable the Flow Record Cache.
+// Any other value will enable the FRC
+#ifndef ADAPTER_CS_FRC_ENABLED
+#define ADAPTER_CS_FRC_ENABLED               1
+#endif // ADAPTER_CS_FRC_ENABLED
+
+// Set to 0 to disable the Transform Record Cache.
+// Any other value will enable the TRC
+#ifndef ADAPTER_CS_TRC_ENABLED
+#define ADAPTER_CS_TRC_ENABLED               1
+#endif // ADAPTER_CS_TRC_ENABLED
+
+// Set to 0 to disable the ARC4 State Record Cache.
+// Any other value will enable the ARC4RC
+#ifndef ADAPTER_CS_ARC4RC_ENABLED
+#define ADAPTER_CS_ARC4RC_ENABLED            1
+#endif // ADAPTER_CS_ARC4RC_ENABLED
+
+// Set to 0 to disable the FLUE Cache. Any other value will enable the FLUEC
+#ifndef ADAPTER_CS_FLUE_LOOKUP_CACHED
+#define ADAPTER_CS_FLUE_LOOKUP_CACHED        1
+#endif // ADAPTER_CS_FLUE_LOOKUP_CACHED
+
+#ifndef ADAPTER_CS_FLUE_PREFETCH_XFORM
+#define ADAPTER_CS_FLUE_PREFETCH_XFORM       1
+#endif // ADAPTER_CS_FLUE_PREFETCH_XFORM
+
+#ifndef ADAPTER_CS_FLUE_PREFETCH_ARC4
+#define ADAPTER_CS_FLUE_PREFETCH_ARC4        0
+#endif // ADAPTER_CS_FLUE_PREFETCH_ARC4
+
+// This parameter enables the EIP-207 Record Cache support when defined
+//#define ADAPTER_CS_RC_SUPPORT
+
+// This parameter defines the maximum supported number of flow hash tables
+#ifndef ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE    1
+#endif
+
+#ifndef ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE
+#define ADAPTER_CS_GLOBAL_MAX_NOF_CE_TO_USE  1
+#endif
+
+// EIP-207 global control device ID, keep undefined if RPM for EIP-207 not used
+//#define ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID     0
+
+// Enable use of meta-data in input and output tokens,
+// EIP-207 firmware must support this if enabled
+//#define ADAPTER_CS_GLOBAL_IOTOKEN_METADATA_ENABLE
+
+// Enable CFH headers.
+//#define ADAPTER_CS_GLOBAL_CFH_ENABLE
+
+// Configure the adapter for ICE OCE configuration
+//#define ADAPTER_CS_GLOBAL_SRV_ICEOCE
+
+// Configure that adapter for ICE configuration
+//#define ADAPTER_CS_GLOBAL_SRV_ICEO
+
+// Enable PktID incrementing on egress tunnel headers.
+//#define ADAPTER_CS_GLOBAL_INCREMENT_PKTID
+
+// ECN control for ingress packets.
+#ifndef ADAPTER_CS_GLOBAL_ECN_CONTROL
+#define ADAPTER_CS_GLOBAL_ECN_CONTROL 0
+#endif
+
+// Record header alignment for DTLS records headers in decrypted packets.
+#ifndef ADAPTER_CS_GLOBAL_DTLS_HDR_ALIGN
+#define ADAPTER_CS_GLOBAL_DTLS_HDR_ALIGN 0
+#endif
+
+#ifndef ADAPTER_CS_GLOBAL_TRANSFORM_REDIRECT_ENABLE
+#define ADAPTER_CS_GLOBAL_TRANSFORM_REDIRECT_ENABLE 0
+#endif
+
+// Defer DTLS packets type CCS to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_CCS
+// Defer DTLS packets type Alert to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_ALERT
+// Defer DTLS packets type Handshake to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_HANDSHAKE
+// Defer DTLS packets type AppData to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_APPDATA
+// Defer DTLS packets type CAPWAP to slowpath
+//#define ADAPTER_CS_GLOBAL_DTLS_DEFER_CAPWAP
+
+
+#include "c_adapter_cs_ext.h"      // chip-specific extensions
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_cs.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs_ext.h
new file mode 100644
index 0000000..0c94851
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_cs_ext.h
@@ -0,0 +1,38 @@
+/* c_adapter_cs_ext.h
+ *
+ * Internal Configuration File
+ *
+ * Extensions for the Classification hardware.
+ * This file is included from c_adapter_cs.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_CS_EXT_H
+#define INCLUDE_GUARD_C_ADAPTER_CS_EXT_H
+
+
+#ifndef ADAPTER_CS_GLOBAL_DEVICE_NAME
+#define ADAPTER_CS_GLOBAL_DEVICE_NAME   "EIP207_GLOBAL"
+#endif // ADAPTER_CS_GLOBAL_DEVICE_NAME
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_cs_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip202.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip202.h
new file mode 100644
index 0000000..6d23ee2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip202.h
@@ -0,0 +1,306 @@
+/* c_adapter_eip202.h
+ *
+ * Default Adapter EIP-202 configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_EIP202_H
+#define INCLUDE_GUARD_C_ADAPTER_EIP202_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+
+// This parameter enables strict argument checking
+//#define ADAPTER_EIP202_STRICT_ARGS
+
+#ifndef ADAPTER_EIP202_GLOBAL_DEVICE_NAME
+#define ADAPTER_EIP202_GLOBAL_DEVICE_NAME    "EIP202_GLOBAL"
+#endif // ADAPTER_EIP202_GLOBAL_DEVICE_NAME
+
+#ifndef ADAPTER_EIP202_DRIVER_NAME
+#define ADAPTER_EIP202_DRIVER_NAME           "Security-IP"
+#endif
+
+// This parameter enables the byte swap in 32-bit words
+// for the EIP-202 CD Manager master interface
+//#define ADAPTER_EIP202_CDR_BYTE_SWAP_ENABLE
+
+// This parameter enables the byte swap in 32-bit words
+// for the EIP-202 RD Manager master interface
+//#define ADAPTER_EIP202_RDR_BYTE_SWAP_ENABLE
+
+// Enables the EIP-207 Record Cache interface for DMA banks
+//#define ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+// Enables the EIP-207 Record Cache interface for record cache invalidation
+//#define ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+
+// This parameter enables the EIP-207 Record Cache interface
+// for the record invalidation via the SHDevXS API.
+// When not defined the Record Cache will be accessed directly
+// via the EIP-207 Record Cache Driver Library API.
+// This parameter must be defined together with ADAPTER_EIP202_RC_SUPPORT
+// for the Record Cache access via the SHDevXS API.
+//#define ADAPTER_EIP202_USE_SHDEVXS
+
+// This parameter enables the EIP-202 64-bit DMA address support
+//#define ADAPTER_EIP202_64BIT_DEVICE
+
+// This parameter enables the DMA banks support
+//#define ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+// This parameter enables the EIP-202 separate rings
+// (CDR used separately from RDR)
+//#define ADAPTER_EIP202_SEPARATE_RINGS
+
+// This parameter enables the EIP-202 scatter-gather support
+//#define ADAPTER_EIP202_ENABLE_SCATTERGATHER
+
+// This parameter disables bounce buffers
+//#define ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+// This parameter configures the maximum number of transform records
+#ifndef ADAPTER_EIP202_TRANSFORM_RECORD_COUNT
+#error "ADAPTER_EIP202_TRANSFORM_RECORD_COUNT is not defined"
+#endif
+
+// This parameter configures the maximum byte count of one transform record
+#ifndef ADAPTER_EIP202_TRANSFORM_RECORD_BYTE_COUNT
+#error "ADAPTER_EIP202_TRANSFORM_RECORD_BYTE_COUNT is not defined"
+#endif
+
+#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+// This parameter enables the EIP-202 interrupt support
+//#define ADAPTER_EIP202_INTERRUPTS_ENABLE
+
+#ifndef ADAPTER_EIP202_INTERRUPTS_TRACEFILTER
+#define ADAPTER_EIP202_INTERRUPTS_TRACEFILTER   0
+#endif
+
+#ifndef ADAPTER_EIP202_PHY_CDR0_IRQ
+#define ADAPTER_EIP202_PHY_CDR0_IRQ     0
+#endif
+
+#ifndef ADAPTER_EIP202_CDR0_INT_NAME
+#define ADAPTER_EIP202_CDR0_INT_NAME    "EIP202-CDR0"
+#endif
+
+#ifndef ADAPTER_EIP202_PHY_RDR0_IRQ
+#define ADAPTER_EIP202_PHY_RDR0_IRQ     1
+#endif
+
+#ifndef ADAPTER_EIP202_RDR0_INT_NAME
+#define ADAPTER_EIP202_RDR0_INT_NAME    "EIP202-RDR0"
+#endif
+
+#ifndef ADAPTER_PHY_EIP202_DFE0_IRQ
+#define ADAPTER_PHY_EIP202_DFE0_IRQ     0
+#endif
+
+#ifndef ADAPTER_EIP202_DFE0_INT_NAME
+#define ADAPTER_EIP202_DFE0_INT_NAME    "EIP202-DFE0"
+#endif
+
+#ifndef ADAPTER_PHY_EIP202_DSE0_IRQ
+#define ADAPTER_PHY_EIP202_DSE0_IRQ     1
+#endif
+
+#ifndef ADAPTER_EIP202_DSE0_INT_NAME
+#define ADAPTER_EIP202_DSE0_INT_NAME    "EIP202-DSE0"
+#endif
+
+#ifndef ADAPTER_PHY_EIP202_RING0_IRQ
+#define ADAPTER_PHY_EIP202_RING0_IRQ    16
+#endif
+
+#ifndef ADAPTER_EIP202_RING0_INT_NAME
+#define ADAPTER_EIP202_RING0_INT_NAME   "EIP202-RING0"
+#endif
+
+#ifndef ADAPTER_PHY_EIP202_PE0_IRQ
+#define ADAPTER_PHY_EIP202_PE0_IRQ      24
+#endif
+
+#ifndef ADAPTER_EIP202_PE0_INT_NAME
+#define ADAPTER_EIP202_PE0_INT_NAME     "EIP202-PE0"
+#endif
+
+#ifndef ADAPTER_EIP202_MAX_PACKETS
+#define ADAPTER_EIP202_MAX_PACKETS      32
+#endif
+
+#ifndef ADAPTER_EIP202_MAX_LOGICDESCR
+#define ADAPTER_EIP202_MAX_LOGICDESCR   32
+#endif
+
+#ifndef ADAPTER_EIP202_BANK_SA
+#define ADAPTER_EIP202_BANK_SA          0
+#endif
+
+#ifndef ADAPTER_EIP202_BANK_RING
+#define ADAPTER_EIP202_BANK_RING        0
+#endif
+
+// This parameter enables the endianness conversion by the Host CPU
+// for the ring descriptors
+//#define ADAPTER_EIP202_ARMRING_ENABLE_SWAP
+
+#ifndef ADAPTER_EIP202_DESCRIPTORDONECOUNT
+#define ADAPTER_EIP202_DESCRIPTORDONECOUNT      1
+#endif
+
+#ifndef ADAPTER_EIP202_DESCRIPTORDONETIMEOUT
+#define ADAPTER_EIP202_DESCRIPTORDONETIMEOUT    0
+#endif
+
+#ifndef ADAPTER_EIP202_DEVICE_COUNT
+#define ADAPTER_EIP202_DEVICE_COUNT     1
+#endif
+
+#ifndef ADAPTER_EIP202_DEVICES
+#error "ADAPTER_EIP202_DEVICES not defined"
+#endif
+
+#ifndef ADAPTER_EIP202_IRQS
+#error "ADAPTER_EIP202_IRQS not defined"
+#endif
+
+//Set this if the IRQs for the second ring (Ring 1) are used.
+//#define ADAPTER_EIP202_HAVE_RING1_IRQ
+
+// Request the IRQ through the UMDevXS driver.
+//#define ADAPTER_EIP202_USE_UMDEVXS_IRQ
+
+// Enable this parameter to switch off the automatic calculation of the global
+// and ring data transfer size and threshold values
+//#define ADAPTER_EIP202_AUTO_THRESH_DISABLE
+
+#ifdef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+//#define ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT    16
+//#define ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT   12
+//#define ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT    80
+//#define ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT   20
+#endif
+
+// Provide manually CDR and RDR configuration parameters
+//#define ADAPTER_EIP202_RING_MANUAL_CONFIGURE
+
+// Derive CDR and RDR configuration parameters from local CDR options register
+//#define ADAPTER_EIP202_RING_LOCAL_CONFIGURE
+
+// Provide manually CDR and RDR configuration parameters
+#ifdef ADAPTER_EIP202_RING_MANUAL_CONFIGURE
+// Host interface data width:
+//   0 = 32 bits, 1 = 64 bits, 2 = 128 bits, 3 = 256 bits
+#ifndef ADAPTER_EIP202_HOST_DATA_WIDTH
+#define ADAPTER_EIP202_HOST_DATA_WIDTH      0
+#endif
+
+// Command Descriptor FIFO size, the actual size is 2^CF_Size 32-bit words
+#ifndef ADAPTER_EIP202_CF_SIZE
+#define ADAPTER_EIP202_CF_SIZE              5
+#endif
+
+// Result Descriptor FIFO size, the actual size is 2^RF_Size 32-bit words
+#ifndef ADAPTER_EIP202_RF_SIZE
+#define ADAPTER_EIP202_RF_SIZE              5
+#endif
+
+#endif // ADAPTER_EIP202_RING_CONFIGURE
+
+#ifndef ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT
+#define ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT   6
+#endif
+
+#ifndef ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT
+#define ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT    16
+#endif
+
+#ifndef ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT
+#define ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT   2
+#endif
+
+// Define if the hardware uses bits in record pointers to distinguish types.
+//#define ADAPTER_EIP202_USE_POINTER_TYPES
+
+// Define if record invalidate commands allow NULL packet pointers
+//#define ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+
+// Define if the hardware does not use large transforms.
+//#define ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
+
+// Default DMA buffer allocation alignment is 4 bytes
+#ifndef ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT
+#define ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT     4
+#endif
+
+// Some applications allocate network packets at unaligned addresses.
+// To avoid bouncing these buffers, you can allow unaligned buffers if
+// caching is properly handled in hardware.
+//#define ADAPTER_EIP202_ALLOW_UNALIGNED_DMA
+
+// EIP-202 Ring manager device ID, keep undefined if RPM for EIP-202 not used
+//#define ADAPTER_PEC_RPM_EIP202_DEVICE0_ID  0
+
+// Default Command Descriptor offset (1 32-bit words)
+// This value must be set to the CPU Data Cache line size if the Command
+// Descriptor Ring is allocated in the cached DMA memory and configured as
+// non-overlapping (separate) with the Result Descriptor Ring.
+// Otherwise the Adapter will set the offset value equal to the Command
+// Descriptor Size aligned for the required DMA buffer alignment and the
+// DMA HW interface alignment (the latter only if configured).
+#ifndef ADAPTER_EIP202_CD_OFFSET_BYTE_COUNT
+#define ADAPTER_EIP202_CD_OFFSET_BYTE_COUNT     \
+                        ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT
+#endif
+
+// Default Result Descriptor offset (1 32-bit words)
+// This value must be set to the CPU Data Cache line size if the Result
+// Descriptor Ring is allocated in the cached DMA memory and configured as
+// non-overlapping (separate) with the Command Descriptor Ring.
+// Otherwise the Adapter will set the offset value equal to the Command
+// Descriptor Size aligned for the required DMA buffer alignment and the
+// DMA HW interface alignment (the latter only if configured).
+#ifndef ADAPTER_EIP202_RD_OFFSET_BYTE_COUNT
+#define ADAPTER_EIP202_RD_OFFSET_BYTE_COUNT     \
+                        ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT
+#endif
+
+// Additional Token Pointer Descriptor Mode, e.g. EIP-202 Command Descriptor
+// will contain an address of the DMA buffer where the EIP-96 Instruction Token
+// is stored.
+// When set to 1 the token data can be stored in a separate from the descriptor
+// DMA buffer, otherwise must be set to 0
+#ifndef ADAPTER_EIP202_CDR_ATP_PRESENT
+#define ADAPTER_EIP202_CDR_ATP_PRESENT      1
+#endif
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_eip202.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip74.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip74.h
new file mode 100644
index 0000000..b8aee9e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_eip74.h
@@ -0,0 +1,77 @@
+/* c_adapter_eip74.h
+ *
+ * Default Adapter Global configuration for EIP-74
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_EIP74_H
+#define INCLUDE_GUARD_C_ADAPTER_EIP74_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+
+#ifndef ADAPTER_EIP74_DEVICE_NAME
+#define ADAPTER_EIP74_DEVICE_NAME            "EIP74"
+#endif // ADAPTER_EIP74_DEVICE_NAME
+
+#ifndef ADAPTER_EIP74_RESET_MAX_RETRIES
+#define ADAPTER_EIP74_RESET_MAX_RETRIES      1000
+#endif // ADAPTER_EIP74_RESET_MAX_RETRIES
+
+
+// EIP-74 generate block size
+#ifndef ADAPTER_EIP74_GEN_BLK_SIZE
+#define ADAPTER_EIP74_GEN_BLK_SIZE           4095
+#endif
+
+// EIP-74 reseed threshold.
+#ifndef ADAPTER_EIP74_RESEED_THR
+#define ADAPTER_EIP74_RESEED_THR             0xffffffff
+#endif
+
+// EIP-74 reaseed early wrning threshold.
+#ifndef ADAPTER_EIP74_RESEED_THR_EARLY
+#define ADAPTER_EIP74_RESEED_THR_EARLY       0xff000000
+#endif
+
+// Define if EIP-74 uses interrupts.
+//ADAPTER_EIP74_INTERRUPTS_ENABLE
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+#ifndef ADAPTER_EIP74_ERR_IRQ
+#define ADAPTER_EIP74_ERR_IRQ           0
+#endif
+#ifndef ADAPTER_EIP74_RES_IRQ
+#define ADAPTER_EIP74_RES_IRQ           0
+#endif
+#endif
+
+// EIP-74 DRBG device ID, keep undefined if RPM for EIP-74 not used
+//#define ADAPTER_PEC_RPM_EIP74_DEVICE0_ID  0
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_eip74.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_firmware.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_firmware.h
new file mode 100644
index 0000000..156a0b8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_firmware.h
@@ -0,0 +1,52 @@
+/* c_adapter_firmware.h
+ *
+ * Default Firmware Adapter Module Configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_ADAPTER_FIRMWARE_H_
+#define C_ADAPTER_FIRMWARE_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Driver Framework configuration
+#include "cs_adapter.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+#ifndef ADAPTER_FIRMWARE_NAMELEN_MAX
+#define ADAPTER_FIRMWARE_NAMELEN_MAX  128
+#endif
+
+#ifndef ADAPTER_FIRMWARE_PATH_PREFIX
+#define ADAPTER_FIRMWARE_PATH_PREFIX  "/lib/firmware/"
+#endif
+
+
+#endif /* C_ADAPTER_MEMXS_H_ */
+
+
+/* end of file c_adapter_firmware.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_global.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_global.h
new file mode 100644
index 0000000..b79df2e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_global.h
@@ -0,0 +1,94 @@
+/* c_adapter_global.h
+ *
+ * Default Adapter Global configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_GLOBAL_H
+#define INCLUDE_GUARD_C_ADAPTER_GLOBAL_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+#ifndef ADAPTER_GLOBAL_DRIVER_NAME
+#define ADAPTER_GLOBAL_DRIVER_NAME     "Security"
+#endif
+
+#ifndef ADAPTER_GLOBAL_LICENSE
+#define ADAPTER_GLOBAL_LICENSE         "GPL"
+#endif
+
+#ifndef ADAPTER_GLOBAL_PRNG_SEED
+// 8 words to seed the PRNG to provide IVs, input to
+#define ADAPTER_GLOBAL_PRNG_SEED {0x48c24cfd, 0x6c07f742, \
+                                  0xaee75681, 0x0f27c239, \
+                                  0x79947198, 0xe2991275, \
+                                  0x21ac3c7c, 0xd008c4b4}
+#endif
+
+#ifndef ADAPTER_GLOBAL_DEVICE_NAME
+#define ADAPTER_GLOBAL_DEVICE_NAME           "EIP197_GLOBAL"
+#endif // ADAPTER_GLOBAL_DEVICE_NAME
+
+#ifndef ADAPTER_GLOBAL_RESET_MAX_RETRIES
+#define ADAPTER_GLOBAL_RESET_MAX_RETRIES      1000
+#endif // ADAPTER_GLOBAL_RESET_MAX_RETRIES
+
+#ifndef ADAPTER_GLOBAL_EIP97_NOF_PES
+#define ADAPTER_GLOBAL_EIP97_NOF_PES          1
+#endif
+
+#ifndef ADAPTER_GLOBAL_EIP97_RINGMASK
+#define ADAPTER_GLOBAL_EIP97_RINGMASK         0x0001
+#endif
+
+#ifndef ADAPTER_GLOBAL_EIP97_PRIOMASK
+#define ADAPTER_GLOBAL_EIP97_PRIOMASK         0
+#endif
+
+// Enables PCI device support
+//#define ADAPTER_GLOBAL_PCI_SUPPORT_ENABLE
+
+// Enables board control device support
+//#define ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+
+// Enables board reset via the board control device
+//#define ADAPTER_GLOBAL_FPGA_HW_RESET_ENABLE
+
+// Runtime Power Management EIP-97 device identifier
+#ifndef ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID
+#define ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID  0
+#endif
+
+#ifndef ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID
+#define ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID 0
+#endif
+
+// Specify a redirect ring.
+//#define ADAPTER_CS_GLOBAL_REDIR_RING 7
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_global.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_memxs.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_memxs.h
new file mode 100644
index 0000000..5d8b9d9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_memxs.h
@@ -0,0 +1,49 @@
+/* c_adapter_memxs.h
+ *
+ * Default MemXS Adapter Module Configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef C_ADAPTER_MEMXS_H_
+#define C_ADAPTER_MEMXS_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Driver Framework configuration
+#include "cs_hwpal.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Here is the dependency on the Driver Framework configuration
+// via the MemXS configuration
+#ifndef HWPAL_DEVICES
+#error "Expected HWPAL_DEVICES defined by cs_memxs.h"
+#endif
+
+
+#endif /* C_ADAPTER_MEMXS_H_ */
+
+
+/* end of file c_adapter_memxs.h */
+
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pcl.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pcl.h
new file mode 100644
index 0000000..cb969ea
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pcl.h
@@ -0,0 +1,136 @@
+/* c_adapter_pcl.h
+ *
+ * Default PCL Adapter configuration.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_PCL_H
+#define INCLUDE_GUARD_C_ADAPTER_PCL_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+#ifndef ADAPTER_PCL_DEVICE_NAME
+#define ADAPTER_PCL_DEVICE_NAME                         "PCL_Device"
+#endif
+
+#ifndef ADAPTER_PCL_BANK_FLOWTABLE
+#define ADAPTER_PCL_BANK_FLOWTABLE                      0
+#endif
+
+#ifndef ADAPTER_PCL_BANK_TRANSFORM
+#define ADAPTER_PCL_BANK_TRANSFORM                      0
+#endif
+
+#ifndef ADAPTER_PCL_BANK_FLOW
+#define ADAPTER_PCL_BANK_FLOW                           0
+#endif
+
+//#define ADAPTER_PCL_ENABLE
+
+// This parameters enables use of the DMA banks
+//#define ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+
+#ifndef ADAPTER_PCL_ENABLE_FLUE_CACHE
+#define ADAPTER_PCL_ENABLE_FLUE_CACHE false
+#endif
+
+#ifndef ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#define ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE      1
+#endif
+
+#ifndef ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT
+#define ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT             1024
+#endif
+
+#if defined(ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE) && \
+    !defined(ADAPTER_PCL_FLOW_RECORD_COUNT)
+#define ADAPTER_PCL_FLOW_RECORD_COUNT     ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT
+#endif
+
+#if defined(ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE) && \
+    !defined(ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT)
+#error "ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT is not defined"
+#endif
+
+#if defined(ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE) && \
+    !defined(ADAPTER_TRANSFORM_RECORD_COUNT)
+#error "ADAPTER_TRANSFORM_RECORD_COUNT is not defined"
+#endif
+
+#if defined(ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE) && \
+    !defined(ADAPTER_TRANSFORM_RECORD_BYTE_COUNT)
+#error "ADAPTER_TRANSFORM_RECORD_BYTE_COUNT is not defined"
+#endif
+
+// Number of tries to wait until a flow can be ssafely removed.
+#ifndef ADAPTER_PCL_FLOW_REMOVE_MAX_TRIES
+#define ADAPTER_PCL_FLOW_REMOVE_MAX_TRIES               100
+#endif
+
+// Delay between tries to check that a flow can be safely removed.
+// Delay is in milliseconds. If it is specified as zero, no delay is inserted.
+#ifndef ADAPTER_PCL_FLOW_REMOVE_DELAY
+#define ADAPTER_PCL_FLOW_REMOVE_DELAY                   10
+#endif
+
+// Number of overflow buckets associated with hash table
+// (defaults here to: number of hash table entries / 16)
+#ifndef ADAPTER_PCL_FLOW_HASH_OVERFLOW_COUNT
+#define ADAPTER_PCL_FLOW_HASH_OVERFLOW_COUNT \
+    (ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT / 16)
+#endif
+
+// Default FLUE device name
+#ifndef ADAPTER_PCL_FLUE_DEFAULT_DEVICE_NAME
+#define ADAPTER_PCL_FLUE_DEFAULT_DEVICE_NAME            "EIP207_FLUE0"
+#endif
+
+// Maximum number of FLUE device instances to be supported
+#ifndef ADAPTER_PCL_MAX_FLUE_DEVICES
+#define ADAPTER_PCL_MAX_FLUE_DEVICES                    1
+#endif
+
+// Device numbering: max number of final digits in device instance name
+// eg. value of 1 allows 0-9, value of 2 allows 0-99
+#ifndef ADAPTER_PCL_MAX_DEVICE_DIGITS
+#define ADAPTER_PCL_MAX_DEVICE_DIGITS                   1
+#endif
+
+#ifndef ADAPTER_PCL_LIST_ID_OFFSET
+#error "ADAPTER_PCL_LIST_ID_OFFSET is not defined"
+#endif
+
+// Default DMA buffer allocation alignment is 4 bytes
+#ifndef ADAPTER_PCL_DMA_ALIGNMENT_BYTE_COUNT
+#define ADAPTER_PCL_DMA_ALIGNMENT_BYTE_COUNT            4
+#endif
+
+// EIP-207 flow control device ID, keep undefined if RPM for EIP-207 not used
+//#define ADAPTER_PCL_RPM_EIP207_DEVICE_ID                0
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_pcl.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pec.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pec.h
new file mode 100644
index 0000000..bddf6b1
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/c_adapter_pec.h
@@ -0,0 +1,79 @@
+/* c_adapter_pec.h
+ *
+ * Default Adapter PEC configuration
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_ADAPTER_PEC_H
+#define INCLUDE_GUARD_C_ADAPTER_PEC_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+
+/****************************************************************************
+ * Adapter general configuration parameters
+ */
+
+#ifndef ADAPTER_PEC_BANK_PACKET
+#define ADAPTER_PEC_BANK_PACKET         0
+#endif
+
+#ifndef ADAPTER_PEC_BANK_TOKEN
+#define ADAPTER_PEC_BANK_TOKEN          0
+#endif
+
+#ifndef ADAPTER_PEC_BANK_SA
+#define ADAPTER_PEC_BANK_SA             0
+#endif
+
+//#define ADAPTER_PEC_STRICT_ARGS
+
+#ifndef ADAPTER_PEC_DEVICE_COUNT
+#define ADAPTER_PEC_DEVICE_COUNT        1
+#endif
+
+#ifndef ADAPTER_PEC_MAX_PACKETS
+#define ADAPTER_PEC_MAX_PACKETS         32
+#endif
+
+#ifndef ADAPTER_PEC_MAX_LOGICDESCR
+#define ADAPTER_PEC_MAX_LOGICDESCR      32
+#endif
+
+//#define ADAPTER_PEC_SEPARATE_RINGS
+//#define ADAPTER_PEC_ENABLE_SCATTERGATHER
+//#define ADAPTER_PEC_INTERRUPTS_ENABLE
+//#define ADAPTER_PEC_ARMRING_ENABLE_SWAP
+
+// Remove bounce buffers support
+//#define ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+
+// EIP-202 Ring manager device ID, keep undefined if RPM for EIP-202 not used
+//#define ADAPTER_PEC_RPM_EIP202_DEVICE0_ID  0
+
+
+#endif /* Include Guard */
+
+
+/* end of file c_adapter_pec.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_alloc.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_alloc.h
new file mode 100644
index 0000000..77393f6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_alloc.h
@@ -0,0 +1,68 @@
+/* adapter_alloc.h
+ *
+ * Linux kernel-space implementation of the Adapter buffer allocation
+ * functionality.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_ALLOC_H_
+#define ADAPTER_ALLOC_H_
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Linux Kernel API
+#include <linux/kernel.h>
+#include <linux/slab.h>         // kmalloc, kfree
+#include <linux/hardirq.h>      // in_atomic
+
+
+/*----------------------------------------------------------------------------
+  Adapter_Alloc
+*/
+static inline void *
+Adapter_Alloc(unsigned int size)
+{
+    if (size > 0) // Many callers do not check if requested size is non-zero
+        // kmalloc() may return non-NULL for size=0
+        return kmalloc(size, in_atomic() ? GFP_ATOMIC : GFP_KERNEL);
+    else
+        return NULL; // ... but only extreme optimists do not check the result!
+}
+
+
+/*----------------------------------------------------------------------------
+  Adapter_Free
+*/
+static inline void
+Adapter_Free(void *p)
+{
+    if (p != NULL)
+    {
+        kfree(p); // kfree() may take a NULL pointer but why bother
+        p = NULL;
+    }
+}
+
+
+#endif /* ADAPTER_ALLOC_H_ */
+
+
+/* end of file adapter_alloc.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_global_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_global_init_ext.h
new file mode 100644
index 0000000..df9614f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_global_init_ext.h
@@ -0,0 +1,100 @@
+/* adapter_driver197_global_init_ext.h
+ *
+ * Linux kernel specific Adapter Global Control extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "c_adapter_global.h"   // ADAPTER_GLOBAL_LICENSE
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Global Classification Control Init API
+#include "api_global_eip207.h"
+
+// Global Classification Control Status API
+#include "api_global_status_eip207.h"
+
+// Global Packet I/O Control Init API
+#include "api_global_eip97.h"
+
+// Global Packet I/O Control Status API
+#include "api_global_status_eip97.h"
+
+// Global DRBG Control API
+#include "api_global_eip74.h"
+
+MODULE_LICENSE(ADAPTER_GLOBAL_LICENSE);
+
+// Global Classification Control Init API
+EXPORT_SYMBOL(GlobalControl207_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl207_Init);
+EXPORT_SYMBOL(GlobalControl207_UnInit);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl97_Init);
+EXPORT_SYMBOL(GlobalControl97_UnInit);
+EXPORT_SYMBOL(GlobalControl97_Configure);
+
+// Global Classification Control Status API
+EXPORT_SYMBOL(GlobalControl207_Status_Get);
+EXPORT_SYMBOL(GlobalControl207_GlobalStats_Get);
+EXPORT_SYMBOL(GlobalControl207_ClockCount_Get);
+EXPORT_SYMBOL(GlobalControl207_Firmware_Configure);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_Debug_Statistics_Get);
+EXPORT_SYMBOL(GlobalControl97_DFE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_DSE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Token_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Context_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Interrupt_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_OutXfer_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Reseed);
+EXPORT_SYMBOL(GlobalControl97_Interfaces_Get);
+
+// Global DRBG Control API
+EXPORT_SYMBOL(GlobalControl74_Init);
+EXPORT_SYMBOL(GlobalControl74_UnInit);
+EXPORT_SYMBOL(GlobalControl74_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl74_Status_Get);
+EXPORT_SYMBOL(GlobalControl74_Reseed);
+EXPORT_SYMBOL(GlobalControl74_Clear);
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+EXPORT_SYMBOL(GlobalControl74_Notify_Request);
+#endif
+
+module_init(Driver197_Global_Init);
+module_exit(Driver197_Global_Exit);
+
+/* end of file adapter_driver197_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_init_ext.h
new file mode 100644
index 0000000..bc24a70
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_init_ext.h
@@ -0,0 +1,125 @@
+/* adapter_driver197_init_ext.h
+ *
+ * Linux kernel specific Adapter extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Global Classification Control Init API
+#include "api_global_eip207.h"
+
+// Global Classification Control Status API
+#include "api_global_status_eip207.h"
+
+// Global Packet I/O Control Init API
+#include "api_global_eip97.h"
+
+// Global Packet I/O Control Status API
+#include "api_global_status_eip97.h"
+
+// Global DRBG Control API
+#include "api_global_eip74.h"
+
+#include "api_dmabuf.h"     // DMABuf API
+
+#include "device_mgmt.h" // Device_Find
+#include "device_rw.h" // Device_Read32/Device_Write32
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+MODULE_LICENSE(ADAPTER_LICENSE);
+
+module_init(Driver197_Init);
+module_exit(Driver197_Exit);
+
+// Global Classification Control Init API
+EXPORT_SYMBOL(GlobalControl207_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl207_Init);
+EXPORT_SYMBOL(GlobalControl207_UnInit);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl97_Init);
+EXPORT_SYMBOL(GlobalControl97_UnInit);
+EXPORT_SYMBOL(GlobalControl97_Configure);
+
+// Global Classification Control Status API
+EXPORT_SYMBOL(GlobalControl207_Status_Get);
+EXPORT_SYMBOL(GlobalControl207_GlobalStats_Get);
+EXPORT_SYMBOL(GlobalControl207_ClockCount_Get);
+EXPORT_SYMBOL(GlobalControl207_Firmware_Configure);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_Debug_Statistics_Get);
+EXPORT_SYMBOL(GlobalControl97_DFE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_DSE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Token_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Context_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Interrupt_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_OutXfer_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Reseed);
+EXPORT_SYMBOL(GlobalControl97_Interfaces_Get);
+
+// Global DRBG Control API
+EXPORT_SYMBOL(GlobalControl74_Init);
+EXPORT_SYMBOL(GlobalControl74_UnInit);
+EXPORT_SYMBOL(GlobalControl74_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl74_Status_Get);
+EXPORT_SYMBOL(GlobalControl74_Reseed);
+EXPORT_SYMBOL(GlobalControl74_Clear);
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+EXPORT_SYMBOL(GlobalControl74_Notify_Request);
+#endif
+
+EXPORT_SYMBOL(DMABuf_NULLHandle);
+EXPORT_SYMBOL(DMABuf_Handle_IsSame);
+EXPORT_SYMBOL(DMABuf_Alloc);
+EXPORT_SYMBOL(DMABuf_Register);
+EXPORT_SYMBOL(DMABuf_Release);
+
+
+EXPORT_SYMBOL(Device_Find);
+EXPORT_SYMBOL(Device_Read32);
+EXPORT_SYMBOL(Device_Write32);
+
+// PEC API LKM implementation extensions
+#include "adapter_pec_lkm_ext.h"
+
+#ifdef ADAPTER_PCL_ENABLE
+// PCL API LKM implementation extensions
+#include "adapter_pcl_lkm_ext.h"
+#endif /* ADAPTER_PCL_ENABLE */
+
+
+/* end of file adapter_driver197_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_init_ext.h
new file mode 100644
index 0000000..e3b4fa9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_init_ext.h
@@ -0,0 +1,59 @@
+/* adapter_driver197_pec_init_ext.h
+ *
+ * Linux kernel specific Adapter extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_dmabuf.h"     // DMABuf API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+MODULE_LICENSE(ADAPTER_LICENSE);
+
+module_init(Driver197_PEC_Init);
+module_exit(Driver197_PEC_Exit);
+
+EXPORT_SYMBOL(DMABuf_NULLHandle);
+EXPORT_SYMBOL(DMABuf_Handle_IsSame);
+EXPORT_SYMBOL(DMABuf_Alloc);
+EXPORT_SYMBOL(DMABuf_Register);
+EXPORT_SYMBOL(DMABuf_Release);
+
+
+// PEC API LKM implementation extensions
+#include "adapter_pec_lkm_ext.h"
+
+
+/* end of file adapter_driver197_pec_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_pcl_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_pcl_init_ext.h
new file mode 100644
index 0000000..8631fcb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver197_pec_pcl_init_ext.h
@@ -0,0 +1,64 @@
+/* adapter_driver197_pec_pcl_init_ext.h
+ *
+ * Linux kernel specific Adapter extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_dmabuf.h"     // DMABuf API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+MODULE_LICENSE(ADAPTER_LICENSE);
+
+module_init(Driver197_PEC_PCL_Init);
+module_exit(Driver197_PEC_PCL_Exit);
+
+EXPORT_SYMBOL(DMABuf_NULLHandle);
+EXPORT_SYMBOL(DMABuf_Handle_IsSame);
+EXPORT_SYMBOL(DMABuf_Alloc);
+EXPORT_SYMBOL(DMABuf_Register);
+EXPORT_SYMBOL(DMABuf_Release);
+
+
+// PEC API LKM implementation extensions
+#include "adapter_pec_lkm_ext.h"
+
+#ifdef ADAPTER_PCL_ENABLE
+// PCL API LKM implementation extensions
+#include "adapter_pcl_lkm_ext.h"
+#endif /* ADAPTER_PCL_ENABLE */
+
+
+/* end of file adapter_driver197_pec_pcl_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_global_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_global_init_ext.h
new file mode 100644
index 0000000..6df7b63
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_global_init_ext.h
@@ -0,0 +1,68 @@
+/* adapter_driver97_global_init_ext.h
+ *
+ * Linux kernel specific Adapter Global Control extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_global.h"   // ADAPTER_GLOBAL_LICENSE
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Global Packet I/O Control Init API
+#include "api_global_eip97.h"
+
+// Global Packet I/O Control Status API
+#include "api_global_status_eip97.h"
+
+
+MODULE_LICENSE(ADAPTER_GLOBAL_LICENSE);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_Capabilities_Get);
+EXPORT_SYMBOL(GlobalControl97_Init);
+EXPORT_SYMBOL(GlobalControl97_UnInit);
+EXPORT_SYMBOL(GlobalControl97_Configure);
+
+// Global Packet I/O Control Status API
+EXPORT_SYMBOL(GlobalControl97_DFE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_DSE_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Token_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Context_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_Interrupt_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_OutXfer_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Status_Get);
+EXPORT_SYMBOL(GlobalControl97_PRNG_Reseed);
+
+module_init(Driver97_Global_Init);
+module_exit(Driver97_Global_Exit);
+
+/* end of file adapter_driver97_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_init_ext.h
new file mode 100644
index 0000000..f01b150
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_init_ext.h
@@ -0,0 +1,59 @@
+/* adapter_driver97_init_ext.h
+ *
+ * Linux kernel specific Adapter extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_dmabuf.h"     // DMABuf API
+
+
+MODULE_LICENSE(ADAPTER_LICENSE);
+
+module_init(Driver97_Init);
+module_exit(Driver97_Exit);
+
+EXPORT_SYMBOL(DMABuf_NULLHandle);
+EXPORT_SYMBOL(DMABuf_Handle_IsSame);
+EXPORT_SYMBOL(DMABuf_Alloc);
+EXPORT_SYMBOL(DMABuf_Register);
+EXPORT_SYMBOL(DMABuf_Release);
+
+
+// PEC API LKM implementation extensions
+#include "adapter_pec_lkm_ext.h"
+
+
+/* end of file adapter_driver97_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_pec_init_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_pec_init_ext.h
new file mode 100644
index 0000000..1152aa5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_driver97_pec_init_ext.h
@@ -0,0 +1,59 @@
+/* adapter_driver97_pec_init_ext.h
+ *
+ * Linux kernel specific Adapter extensions
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_dmabuf.h"     // DMABuf API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+MODULE_LICENSE(ADAPTER_LICENSE);
+
+module_init(Driver97_PEC_Init);
+module_exit(Driver97_PEC_Exit);
+
+EXPORT_SYMBOL(DMABuf_NULLHandle);
+EXPORT_SYMBOL(DMABuf_Handle_IsSame);
+EXPORT_SYMBOL(DMABuf_Alloc);
+EXPORT_SYMBOL(DMABuf_Register);
+EXPORT_SYMBOL(DMABuf_Release);
+
+
+// PEC API LKM implementation extensions
+#include "adapter_pec_lkm_ext.h"
+
+
+/* end of file adapter_driver97_pec_init_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_lock_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_lock_ext.h
new file mode 100644
index 0000000..6523e16
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_lock_ext.h
@@ -0,0 +1,51 @@
+/* adapter_lock_ext.h
+ *
+ * Adapter concurrency (locking) management
+ * extensions for Linux kernel-space
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_ADAPTER_LOCK_EXT_H
+#define INCLUDE_GUARD_ADAPTER_LOCK_EXT_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Linux Kernel API
+#include <linux/spinlock.h>     // spinlock_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define ADAPTER_LOCK_DEFINE(Lock)   DEFINE_SPINLOCK(Lock)
+
+/* Lock structure, so it can be part of another structure or array */
+typedef spinlock_t Adapter_Lock_Struct_t;
+
+/* Initializer for elements of Adapter_Lock_Struct_t */
+#define ADAPTER_LOCK_INITIALIZER __SPIN_LOCK_UNLOCKED(adapter)
+
+#endif // INCLUDE_GUARD_ADAPTER_LOCK_EXT_H
+
+
+/* end of file adapter_lock_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pcl_lkm_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pcl_lkm_ext.h
new file mode 100644
index 0000000..b6c0a47
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pcl_lkm_ext.h
@@ -0,0 +1,69 @@
+/* adapter_pcl_lkm_ext.h
+ *
+ * PCL DTL API Linux kernel implementation extensions
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_PCL_LKM_EXT_H_
+#define ADAPTER_PCL_LKM_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_pcl.h"        // PCL API
+
+#include "api_pcl_dtl.h"    // PCL DTL API
+
+
+EXPORT_SYMBOL(PCL_Init);
+EXPORT_SYMBOL(PCL_UnInit);
+EXPORT_SYMBOL(PCL_Flow_DMABuf_Handle_Get);
+EXPORT_SYMBOL(PCL_Flow_Hash);
+EXPORT_SYMBOL(PCL_Flow_Alloc);
+EXPORT_SYMBOL(PCL_Flow_Add);
+EXPORT_SYMBOL(PCL_Flow_Remove);
+EXPORT_SYMBOL(PCL_Flow_Release);
+EXPORT_SYMBOL(PCL_Flow_Get_ReadOnly);
+EXPORT_SYMBOL(PCL_Transform_Register);
+EXPORT_SYMBOL(PCL_Transform_UnRegister);
+EXPORT_SYMBOL(PCL_Transform_Get_ReadOnly);
+
+EXPORT_SYMBOL(PCL_DTL_Init);
+EXPORT_SYMBOL(PCL_DTL_UnInit);
+EXPORT_SYMBOL(PCL_DTL_Transform_Add);
+EXPORT_SYMBOL(PCL_DTL_Transform_Remove);
+EXPORT_SYMBOL(PCL_DTL_Hash_Remove);
+
+
+#endif // ADAPTER_PCL_LKM_EXT_H_
+
+
+/* end of file adapter_pcl_lkm_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pec_lkm_ext.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pec_lkm_ext.h
new file mode 100644
index 0000000..a7f02f9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/adapter_pec_lkm_ext.h
@@ -0,0 +1,120 @@
+/* adapter_pec_lkm_ext.h
+ *
+ * PEC API implementation,
+ * Linux kernel specific extensions
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef ADAPTER_PEC_LKM_EXT_H_
+#define ADAPTER_PEC_LKM_EXT_H_
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+// Linux Kernel API
+#include <linux/init.h>     // module_init, module_exit
+#include <linux/module.h>   // EXPORT_SYMBOL
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_pec.h"        // PEC API
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+#include "api_pec_sg.h"     // PEC SG API
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+
+#include "iotoken.h"        // IOToken API
+
+#ifdef ADAPTER_AUTO_TOKENBUILDER
+#include "token_builder.h"
+#include "sa_builder.h"
+#include "sa_builder_ipsec.h"
+#include "sa_builder_ssltls.h"
+#include "sa_builder_basic.h"
+// #include "sa_builder_srtp.h"
+#endif
+
+// PEC API
+EXPORT_SYMBOL(PEC_Capabilities_Get);
+EXPORT_SYMBOL(PEC_Init);
+EXPORT_SYMBOL(PEC_UnInit);
+EXPORT_SYMBOL(PEC_SA_Register);
+EXPORT_SYMBOL(PEC_SA_UnRegister);
+EXPORT_SYMBOL(PEC_Packet_Put);
+EXPORT_SYMBOL(PEC_Packet_Get);
+EXPORT_SYMBOL(PEC_Scatter_Preload);
+EXPORT_SYMBOL(PEC_CommandNotify_Request);
+EXPORT_SYMBOL(PEC_ResultNotify_Request);
+EXPORT_SYMBOL(PEC_CD_Control_Write);
+EXPORT_SYMBOL(PEC_RD_Status_Read);
+EXPORT_SYMBOL(PEC_Put_Dump);
+EXPORT_SYMBOL(PEC_Get_Dump);
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+EXPORT_SYMBOL(PEC_SGList_Create);
+EXPORT_SYMBOL(PEC_SGList_Destroy);
+EXPORT_SYMBOL(PEC_SGList_Write);
+EXPORT_SYMBOL(PEC_SGList_Read);
+EXPORT_SYMBOL(PEC_SGList_GetCapacity);
+EXPORT_SYMBOL(PEC_Scatter_PreloadNotify_Request);
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+
+// IOToken API
+EXPORT_SYMBOL(IOToken_Create);
+EXPORT_SYMBOL(IOToken_Parse);
+EXPORT_SYMBOL(IOToken_InWordCount_Get);
+EXPORT_SYMBOL(IOToken_OutWordCount_Get);
+EXPORT_SYMBOL(IOToken_SAAddr_Update);
+EXPORT_SYMBOL(IOToken_SAReuse_Update);
+EXPORT_SYMBOL(IOToken_Mark_Set);
+EXPORT_SYMBOL(IOToken_Mark_Check);
+EXPORT_SYMBOL(IOToken_PacketLegth_Get);
+EXPORT_SYMBOL(IOToken_BypassLegth_Get);
+EXPORT_SYMBOL(IOToken_ErrorCode_Get);
+
+#ifdef ADAPTER_AUTO_TOKENBUILDER
+// SABuilder API
+EXPORT_SYMBOL(SABuilder_GetSizes);
+EXPORT_SYMBOL(SABuilder_BuildSA);
+EXPORT_SYMBOL(SABuilder_Init_ESP);
+EXPORT_SYMBOL(SABuilder_Init_SSLTLS);
+EXPORT_SYMBOL(SABuilder_Init_Basic);
+// EXPORT_SYMBOL(SABuilder_Init_SRTP);
+
+// TokenBuilder API
+EXPORT_SYMBOL(TokenBuilder_GetContextSize);
+EXPORT_SYMBOL(TokenBuilder_BuildContext);
+EXPORT_SYMBOL(TokenBuilder_GetSize);
+EXPORT_SYMBOL(TokenBuilder_BuildToken);
+#endif
+
+
+#endif // ADAPTER_PEC_LKM_EXT_H_
+
+
+/* end of file adapter_pec_lkm_ext.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/dmares_record.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/dmares_record.h
new file mode 100644
index 0000000..8cc0baa
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/lkm/dmares_record.h
@@ -0,0 +1,118 @@
+/* dmares_record.h
+ *
+ * Driver Framework, DMAResource Record Definition
+ *
+ * The document "Driver Framework Porting Guide" contains the detailed
+ * specification of this API. The information contained in this header file
+ * is for reference only.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2010-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_DMARES_REC_H
+#define INCLUDE_GUARD_DMARES_REC_H
+
+
+#include "cs_adapter.h"     // enable switches for conditional fields
+#include "basic_defs.h"     // uint8_t, uint32_t
+
+/*----------------------------------------------------------------------------
+ * AddrTrans_Domain_t
+ *
+ * This is a list of domains that can be supported by the implementation.
+ * Can be used with variables of the DMAResource_AddrDomain_t type
+ *
+ */
+typedef enum
+{
+    DMARES_DOMAIN_UNKNOWN = 0,
+    DMARES_DOMAIN_HOST,
+    DMARES_DOMAIN_HOST_UNALIGNED,
+    DMARES_DOMAIN_BUS
+} AddrTrans_Domain_t;
+
+
+// Maximum number of address/domain pairs stored per DMA resource.
+#define DMARES_ADDRPAIRS_CAPACITY 3
+
+typedef struct
+{
+    uint32_t Magic;     // signature used to validate handles
+
+    // DMA resource properties: Size, Alignment, Bank & fCached
+    DMAResource_Properties_t Props;
+
+    // Storage for upto N address/domain pairs.
+    DMAResource_AddrPair_t AddrPairs[DMARES_ADDRPAIRS_CAPACITY];
+
+    // if true, 32-bit words are swapped when transferred to/from
+    // the DMA resource
+    bool fSwapEndianness;
+
+    // this implementation supports the following allocator references:
+    // 'A' -> this DMA resource has been obtained through DMAResource_Alloc
+    // 'R' -> this DMA resource has been obtained through
+    //        DMAResource_CheckAndRegister using Linux DMA API
+    // 'k' -> this DMA resource has been obtained through
+    //        DMAResource_CheckAndRegister using Linux kmalloc() allocator
+    // 'N' -> used to register buffers that do not need to be DMA-safe
+    // 'T' -> this DMA resource has been obtained through DMAResource_Attach
+    char AllocatorRef;
+
+    // maximum data amount that can be stored in bytes, e.g. allocated size
+    unsigned int BufferSize;
+
+#ifndef ADAPTER_REMOVE_BOUNCEBUFFERS
+    struct
+    {
+        // bounce buffer for DMAResource_CheckAndRegister'ed buffers
+        // note: used only when concurrency is impossible
+        //       (PE source packets allow concurrency!!)
+        DMAResource_Handle_t Bounce_Handle;
+    } bounce;
+#endif
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    struct
+    {
+        // for secure detection of PEC_SGList handles
+        bool IsSGList;
+    } sg;
+#endif
+
+    bool fIsNewSA;
+
+#ifndef ADAPTER_USE_LARGE_TRANSFORM_DISABLE
+    bool fIsLargeTransform;
+#endif
+
+    // Implementation-specific DMA resource context
+    void * Context_p;
+
+    // Type of DMA bank
+    unsigned int BankType;
+
+} DMAResource_Record_t;
+
+#define DMARES_RECORD_MAGIC 0xde42b5e7
+
+
+#endif // INCLUDE_GUARD_DMARES_REC_H
+
+
+/* end of file dmares_record.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/rpm_device_macros.h b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/rpm_device_macros.h
new file mode 100644
index 0000000..e79f568
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/inc/crypto-eip/ddk/slad/rpm_device_macros.h
@@ -0,0 +1,94 @@
+/* rpm_device_macros.h
+ *
+ * Runtime Power Management (RPM) Device Macros API
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2015-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_RPM_DEVICE_MACROS_H
+#define INCLUDE_GUARD_RPM_DEVICE_MACROS_H
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"     // false, IDENTIFIER_NOT_USED
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define RPM_SUCCESS     0   // No error
+
+#define RPM_DEVICE_CAPABILITIES_STR_MACRO     "RPM stubbed"
+
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_INIT_START_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_INIT_START_MACRO(DevId, SuspendFunc, ResumeFunc) RPM_SUCCESS
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_INIT_STOP_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_INIT_STOP_MACRO(DevId) RPM_SUCCESS
+
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_UNINIT_START_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_UNINIT_START_MACRO(DevId, fResume) RPM_SUCCESS
+
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_UNINIT_STOP_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_UNINIT_STOP_MACRO(DevId) RPM_SUCCESS
+
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_IO_START_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_IO_START_MACRO(DevId, flag) RPM_SUCCESS
+
+
+/*----------------------------------------------------------------------------
+ * RPM_DEVICE_IO_STOP_MACRO
+ *
+ * Expands into a single line expression
+ */
+#define RPM_DEVICE_IO_STOP_MACRO(DevId, flag) RPM_SUCCESS
+
+
+#endif /* INCLUDE_GUARD_RPM_DEVICE_MACROS_H */
+
+
+/* rpm_device_macros.h */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c
new file mode 100644
index 0000000..84401f4
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c
@@ -0,0 +1,1720 @@
+/* sa_builder.c
+ *
+ * Main implementation file of the EIP-96 SA builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h"
+
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+#include "token_builder.h"
+#endif
+
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_BASIC_EXTENDED)
+#include "sa_builder_extended_internal.h"
+#include "firmware_eip207_api_flow_cs.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
+unsigned int LargeTransformOffset = SAB_LARGE_TRANSFORM_OFFSET;
+#else
+#define LargeTransformOffset 16
+#endif
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMat
+ *
+ * Copy a key into the SA.
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the SA record.
+ *
+ * offset (input)
+ *   Word offset of the key in the SA record where it must be stored.
+ *
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMat(
+        uint32_t * const Destination_p,
+        const unsigned int offset,
+        const uint8_t * const Source_p,
+        const unsigned int KeyByteCount)
+{
+    uint32_t *dst = Destination_p + offset;
+    const uint8_t *src = Source_p;
+    unsigned int i,j;
+    uint32_t w;
+    if (Destination_p == NULL)
+        return;
+    for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
+    {
+        w=0;
+        for(j=0; j<sizeof(uint32_t); j++)
+            w=(w>>8)|(*src++ << 24);
+        *dst++ = w;
+    }
+    if ((KeyByteCount % sizeof(uint32_t)) != 0)
+    {
+        w=0;
+        for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
+        {
+            w = w | (*src++ << (j*8));
+        }
+        *dst++ = w;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMatSwap
+ *
+ * Copy a key into the SA with the words byte-swapped.
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) to store the data.
+ *
+ * offset (input)
+ *   Word offset of the key in the SA record where it must be stored.
+ *
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMatSwap(
+        uint32_t * const Destination_p,
+        const unsigned int offset,
+        const uint8_t * const Source_p,
+        const unsigned int KeyByteCount)
+{
+    uint32_t *dst = Destination_p + offset;
+    const uint8_t *src = Source_p;
+    unsigned int i,j;
+    uint32_t w;
+
+    if (Destination_p == NULL)
+        return;
+
+    for(i=0; i < KeyByteCount  / sizeof(uint32_t); i++)
+    {
+        w=0;
+
+        for(j=0; j<sizeof(uint32_t); j++)
+            w=(w<<8)|(*src++);
+
+        *dst++ = w;
+    }
+    if ((KeyByteCount % sizeof(uint32_t)) != 0)
+    {
+        w=0;
+        for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
+        {
+            w = w | (*src++ << (24 - j*8));
+        }
+        *dst++ = w;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_ZeroFill
+ *
+ * Fill an area in the SA with zero bytes.
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the SA record.
+ *
+ * offset (input)
+ *   Word offset of the area in the SA that must be zero-filled.
+ *
+ * ByteCount (input)
+ *   Number of bytes to write.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no zeroes
+ * will be written.
+ */
+void
+SABuilderLib_ZeroFill(
+        uint32_t * const Destination_p,
+        const unsigned int offset,
+        const unsigned int ByteCount)
+{
+    uint32_t *dst = Destination_p + offset;
+    unsigned int i;
+    if (Destination_p == NULL)
+        return;
+    for(i=0; i < (ByteCount + sizeof(uint32_t) - 1) / sizeof(uint32_t); i++)
+    {
+        *dst++ = 0;
+    }
+}
+
+#ifdef SAB_ARC4_STATE_IN_SA
+/*----------------------------------------------------------------------------
+ * SABuilder_AlignForARc4State
+ *
+ * Align CurrentOffset to the alignment as specified by
+ * SAB_ARC4_STATE_ALIGN_BYTE_COUNT
+ */
+static unsigned int
+SABuilder_AlignForARc4State(
+        unsigned int CurrentOffset)
+{
+#if SAB_ARC4_STATE_ALIGN_BYTE_COUNT <= 4
+    return CurrentOffset;
+#else
+    uint32_t AlignMask = (SAB_ARC4_STATE_ALIGN_BYTE_COUNT >> 2) - 1;
+    return (CurrentOffset + AlignMask) & ~AlignMask;
+#endif
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetCipherKeys
+ *
+ * Fill in cipher keys and associated command word fields in SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetCipherKeys(
+        SABuilder_Params_t *const SAParams_p,
+        SABuilder_State_t * const SAState_p,
+        uint32_t * const SABuffer_p)
+{
+    /* Fill in crypto-algorithm specific parameters */
+    switch (SAParams_p->CryptoAlgo)
+    {
+    case SAB_CRYPTO_NULL: /* Null crypto, do nothing */
+        break;
+#ifdef SAB_ENABLE_CRYPTO_3DES
+    case SAB_CRYPTO_DES:
+        SAState_p->CipherKeyWords = 2;
+        SAState_p->IVWords = 2;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_DES;
+        break;
+    case SAB_CRYPTO_3DES:
+        SAState_p->CipherKeyWords = 6;
+        SAState_p->IVWords = 2;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_3DES;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_AES
+    case SAB_CRYPTO_AES:
+        switch (SAParams_p->KeyByteCount)
+        {
+        case 16:
+            SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_128;
+            SAState_p->CipherKeyWords = 4;
+            break;
+        case 24:
+            SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_192;
+            SAState_p->CipherKeyWords = 6;
+            break;
+        case 32:
+            SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_256;
+            SAState_p->CipherKeyWords = 8;
+            break;
+        default:
+            LOG_CRIT("SABuilder: Bad key size for AES.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        SAState_p->IVWords = 4;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ARCFOUR
+    case SAB_CRYPTO_ARCFOUR:
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_ARC4;
+        if (SAParams_p->KeyByteCount < 5 ||
+            SAParams_p->KeyByteCount > 16)
+        {
+            LOG_CRIT("SABuilder: Bad key size for ARCFOUR.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        SAState_p->CW1 |= SAParams_p->KeyByteCount;
+        SAState_p->CipherKeyWords =
+            ((unsigned int)SAParams_p->KeyByteCount + sizeof(uint32_t) - 1) /
+            sizeof(uint32_t);
+
+        if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATELESS)
+        {
+            SAState_p->ARC4State = true;
+            SAState_p->CW1 |= SAB_CW1_ARC4_IJ_PTR | SAB_CW1_ARC4_STATE_SEL |
+                SAB_CW1_CRYPTO_STORE;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SM4
+    case SAB_CRYPTO_SM4:
+        SAState_p->CipherKeyWords = 4;
+        SAState_p->IVWords = 4;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_SM4;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_BC0
+    case SAB_CRYPTO_BC0:
+        SAState_p->CipherKeyWords = 8;
+        SAState_p->IVWords = 4;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_BC0 +
+            ((SAParams_p->CryptoParameter & 0x3) << 17) ;
+        SAState_p->CW1 |= SAB_CW1_EXT_CIPHER_SET;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_KASUMI
+    case SAB_CRYPTO_KASUMI:
+        SAState_p->CipherKeyWords = 4;
+        SAState_p->IVWords = 0;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_KASUMI;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SNOW
+    case SAB_CRYPTO_SNOW:
+        SAState_p->CipherKeyWords = 4;
+        SAState_p->IVWords = 4;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_SNOW;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ZUC
+    case SAB_CRYPTO_ZUC:
+        SAState_p->CipherKeyWords = 4;
+        SAState_p->IVWords = 4;
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_ZUC;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+    case SAB_CRYPTO_CHACHA20:
+        SAState_p->CW0 |= SAB_CW0_CRYPTO_CHACHA20;
+        switch (SAParams_p->KeyByteCount)
+        {
+        case 16:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA128;
+            SAState_p->CipherKeyWords = 4;
+            break;
+        case 32:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA256;
+            SAState_p->CipherKeyWords = 8;
+            break;
+        default:
+            LOG_CRIT("SABuilder: Bad key size for Chacha20.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        break;
+#endif
+    default:
+        LOG_CRIT("SABuilder: Unsupported crypto algorithm\n");
+        return SAB_UNSUPPORTED_FEATURE;
+    }
+
+    /* Check block cipher length against provided key  */
+    if (SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+        SAState_p->CipherKeyWords*sizeof(uint32_t) != SAParams_p->KeyByteCount)
+    {
+        LOG_CRIT("SABuilder: Bad cipher key size..\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+#ifdef SAB_STRICT_ARGS_CHECK
+    if ( SAState_p->CipherKeyWords > 0 && SAParams_p->Key_p == NULL)
+    {
+        LOG_CRIT("SABuilder: NULL pointer for Key_p.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20 &&
+        SAParams_p->KeyByteCount == 16)
+    {
+        /* Copy the key twice for 128-bit Chacha20 */
+        SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                SAParams_p->Key_p, SAParams_p->KeyByteCount);
+        SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+    }
+#endif
+    /* Copy the cipher key */
+    SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                            SAParams_p->Key_p, SAParams_p->KeyByteCount);
+
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR)
+        SAState_p->CurrentOffset += 4; /* Always use 4 words for key in ARC4*/
+    else
+        SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+
+    /* Check that wireless algorithms are not used with authentication */
+    if ((SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
+         SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
+         SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC) &&
+        SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+    {
+        LOG_CRIT("SABuilder: "
+                 "Crypto algorithm cannot be combined with authentication.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Handle feedback modes */
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_DES ||
+        SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES ||
+        SAParams_p->CryptoAlgo == SAB_CRYPTO_AES ||
+        SAParams_p->CryptoAlgo == SAB_CRYPTO_SM4 ||
+        SAParams_p->CryptoAlgo == SAB_CRYPTO_BC0)
+    {
+        switch (SAParams_p->CryptoMode)
+        {
+        case SAB_CRYPTO_MODE_ECB:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ECB;
+            SAState_p->IVWords = 0;
+            break;
+        case SAB_CRYPTO_MODE_CBC:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CBC;
+            break;
+        case SAB_CRYPTO_MODE_CFB:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CFB;
+            break;
+        case SAB_CRYPTO_MODE_OFB:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_OFB;
+            break;
+        case SAB_CRYPTO_MODE_CTR:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+            break;
+        case SAB_CRYPTO_MODE_ICM:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ICM;
+            break;
+        case SAB_CRYPTO_MODE_CCM:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+            if (SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM)
+            {
+                LOG_CRIT("SABuilder: crypto CCM requires auth CCM.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            break;
+        case SAB_CRYPTO_MODE_GCM:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+            if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM)
+            {
+                LOG_CRIT("SABuilder: crypto GCM requires auth GCM.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            break;
+        case SAB_CRYPTO_MODE_GMAC:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+            if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
+            {
+                LOG_CRIT("SABuilder: crypto GMAC requires auth GMAC.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            break;
+#ifdef SAB_ENABLE_CRYPTO_XTS
+        case SAB_CRYPTO_MODE_XTS:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS;
+            if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+            {
+                LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            break;
+        case SAB_CRYPTO_MODE_XTS_STATEFUL:
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS | SAB_CW1_XTS_STATEFUL;
+            if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+            {
+                LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            break;
+#endif
+        default:
+            LOG_CRIT("SABuilder: Invalid crypto mode.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+    }
+    else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
+             SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
+             SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC)
+    {
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_F8 ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_UEA2 ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_EEA3)
+
+        {
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_F8_UEA;
+        }
+        else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_BASIC ||
+                 SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ECB)
+        {
+            // Do nothing.
+        }
+        else
+        {
+            LOG_CRIT("SABuilder: Invalid crypto mode for wireless .\n");
+            return SAB_INVALID_PARAMETER;
+        }
+    }
+
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+    else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+    {
+        SAState_p->IVWords = 4;
+        if (SAParams_p->AuthAlgo == SAB_AUTH_POLY1305 ||
+            SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_POLY1305)
+        {
+            SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32 |
+                SAB_CW1_CRYPTO_AEAD;
+        }
+        else if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+        {
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR64)
+            {
+                SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR64;
+            }
+            else
+            {
+                SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32;
+            }
+        }
+        else
+        {
+            LOG_CRIT("SABuilder: Invalid authentication mode for Chacha20 .\n");
+            return SAB_INVALID_PARAMETER;
+        }
+    }
+#endif
+
+    /* The following crypto modes can only be used with AES */
+    if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CCM ||
+          SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GCM ||
+          SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GMAC ||
+          SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS ||
+          SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS_STATEFUL) &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_AES)
+    {
+        LOG_CRIT("SABuilder: crypto mode requires AES.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+    /* The following crypto modes can only be used with AES or SM4 */
+    if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CTR ||
+          SAParams_p->CryptoMode==SAB_CRYPTO_MODE_ICM) &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0)
+    {
+        LOG_CRIT("SABuilder: crypto mode requires AES or SM4.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetAuthSizeAndMode
+ *
+ * Determine the size of the authentication keys and set the required mode
+ * bits in the control words.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated.
+ *
+ * Auth1Words_p (output)
+ *   The number of 32-bit words of the first authentication key.
+ *
+ * Auth2Words_p (output)
+ *   The number of 32-bit words of the second authentication key.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetAuthSizeAndMode(
+        SABuilder_Params_t *const SAParams_p,
+        SABuilder_State_t * const SAState_p,
+        uint32_t * const Auth1Words_p,
+        uint32_t * const Auth2Words_p)
+{
+    unsigned int Auth1Words = 0;
+    unsigned int Auth2Words = 0;
+
+    switch (SAParams_p->AuthAlgo)
+    {
+    case SAB_AUTH_NULL:
+        break;
+#ifdef SAB_ENABLE_AUTH_MD5
+    case SAB_AUTH_HASH_MD5:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_MD5;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 4;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA1
+    case SAB_AUTH_HASH_SHA1:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA1;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 5;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_256
+    case SAB_AUTH_HASH_SHA2_224:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_224;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 8;
+        }
+        break;
+    case SAB_AUTH_HASH_SHA2_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_256;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 8;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_512
+    case SAB_AUTH_HASH_SHA2_384:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_384;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 16;
+        }
+        break;
+    case SAB_AUTH_HASH_SHA2_512:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_512;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 16;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA3
+    case SAB_AUTH_HASH_SHA3_224:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_224;
+        if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+        {
+            Auth1Words = 36;
+        }
+        break;
+    case SAB_AUTH_HASH_SHA3_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_256;
+        if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+        {
+            Auth1Words = 34;
+        }
+        break;
+    case SAB_AUTH_HASH_SHA3_384:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_384;
+        if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+        {
+            Auth1Words = 26;
+        }
+        break;
+    case SAB_AUTH_HASH_SHA3_512:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_512;
+        if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+        {
+            Auth1Words = 18;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SM3
+    case SAB_AUTH_HASH_SM3:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SM3;
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 8;
+        }
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_MD5
+    case SAB_AUTH_SSLMAC_MD5:
+    case SAB_AUTH_HMAC_MD5:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_MD5;
+        Auth1Words = 4;
+        Auth2Words = 4;
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA1
+    case SAB_AUTH_SSLMAC_SHA1:
+        SAState_p->CW0 |= SAB_CW0_AUTH_SSLMAC_SHA1;
+        Auth1Words = 5;
+        break;
+    case SAB_AUTH_HMAC_SHA1:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA1;
+        Auth1Words = 5;
+        Auth2Words = 5;
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_256
+    case SAB_AUTH_HMAC_SHA2_224:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_224;
+        Auth1Words = 8;
+        Auth2Words = 8;
+        break;
+    case SAB_AUTH_HMAC_SHA2_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_256;
+        Auth1Words = 8;
+        Auth2Words = 8;
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_512
+    case SAB_AUTH_HMAC_SHA2_384:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_384;
+        Auth1Words = 16;
+        Auth2Words = 16;
+        break;
+    case SAB_AUTH_HMAC_SHA2_512:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_512;
+        Auth1Words = 16;
+        Auth2Words = 16;
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA3
+    case SAB_AUTH_KEYED_HASH_SHA3_224:
+        SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_224;
+        SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+        Auth1Words = 36;
+        break;
+    case SAB_AUTH_KEYED_HASH_SHA3_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_256;
+        SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+        Auth1Words = 34;
+        break;
+    case SAB_AUTH_KEYED_HASH_SHA3_384:
+        SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_384;
+        SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+        Auth1Words = 26;
+        break;
+    case SAB_AUTH_KEYED_HASH_SHA3_512:
+        SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_512;
+        SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+        Auth1Words = 18;
+        break;
+    case SAB_AUTH_HMAC_SHA3_224:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_224;
+        Auth1Words = 36;
+        break;
+    case SAB_AUTH_HMAC_SHA3_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_256;
+        Auth1Words = 34;
+        break;
+    case SAB_AUTH_HMAC_SHA3_384:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_384;
+        Auth1Words = 26;
+        break;
+    case SAB_AUTH_HMAC_SHA3_512:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_512;
+        Auth1Words = 18;
+        break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SM3
+    case SAB_AUTH_HMAC_SM3:
+        SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SM3;
+        Auth1Words = 8;
+        Auth2Words = 8;
+        break;
+#endif
+    case SAB_AUTH_AES_XCBC_MAC:
+    case SAB_AUTH_AES_CMAC_128:
+        SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
+        Auth1Words = 4;
+        Auth2Words = 4;
+        break;
+    case SAB_AUTH_AES_CMAC_192:
+        SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
+        Auth1Words = 6;
+        Auth2Words = 4;
+        break;
+    case SAB_AUTH_AES_CMAC_256:
+        SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
+        Auth1Words = 8;
+        Auth2Words = 4;
+        break;
+    case SAB_AUTH_AES_CCM:
+        if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM)
+        {
+            LOG_CRIT("SABuilder: auth CCM requires crypto CCM.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        switch (SAParams_p->KeyByteCount)
+        {
+        case 16:
+            Auth1Words = 4;
+            SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
+            break;
+        case 24:
+            Auth1Words = 6;
+            SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
+            break;
+        case 32:
+            Auth1Words = 8;
+            SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
+            break;
+        }
+        Auth2Words = 4;
+        SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+        break;
+#ifdef SAB_ENABLE_CRYPTO_GCM
+    case SAB_AUTH_AES_GCM:
+        if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM)
+        {
+            LOG_CRIT("SABuilder: auth GCM requires crypto GCM.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
+        Auth1Words = 4;
+        SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+        break;
+    case SAB_AUTH_AES_GMAC:
+        if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GMAC)
+        {
+            LOG_CRIT("SABuilder: auth GMAC requires crypto GMAC.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
+        Auth1Words = 4;
+        SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_KASUMI
+    case SAB_AUTH_KASUMI_F9:
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+        {
+            LOG_CRIT("SABuilder: auth KASUMI requires crypto NULL.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        Auth1Words = 4;
+        SAState_p->CW0 |= SAB_CW0_AUTH_KASUMI_F9;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SNOW
+    case SAB_AUTH_SNOW_UIA2:
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+        {
+            LOG_CRIT("SABuilder: auth SNOW requires crypto NULL.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        Auth1Words = 4;
+        SAState_p->CW0 |= SAB_CW0_AUTH_SNOW_UIA2;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ZUC
+    case SAB_AUTH_ZUC_EIA3:
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+        {
+            LOG_CRIT("SABuilder: auth ZUC requires crypto NULL.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        Auth1Words = 4;
+        SAState_p->CW0 |= SAB_CW0_AUTH_ZUC_EIA3;
+        break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+    case SAB_AUTH_KEYED_HASH_POLY1305:
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+        {
+            LOG_CRIT("SABuilder: auth keyed Poly1305 requires crypto NULL.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                                  SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+            Auth1Words = 4;
+            Auth2Words = 8;
+        }
+        else
+        {
+            Auth1Words = 8;
+        }
+        SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_POLY1305;
+        break;
+    case SAB_AUTH_POLY1305:
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20)
+        {
+            LOG_CRIT("SABuilder: auth Poly1305 requires crypto Chacha20.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        SAState_p->CW0 |= SAB_CW0_AUTH_POLY1305;
+        SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK;
+        SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+        break;
+#endif
+    default:
+        LOG_CRIT("SABuilder: Unsupported authentication algorithm\n");
+        return SAB_UNSUPPORTED_FEATURE;
+    }
+
+    *Auth1Words_p = Auth1Words;
+    *Auth2Words_p = Auth2Words;
+    return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetAuthKeys
+ *
+ * Fill in authentication keys and associated command word fields in SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetAuthKeys(
+        SABuilder_Params_t *const SAParams_p,
+        SABuilder_State_t * const SAState_p,
+        uint32_t * const SABuffer_p)
+{
+    unsigned int Auth1Words = 0;
+    unsigned int Auth2Words = 0;
+    SABuilder_Status_t Rc;
+
+    Rc = SABuilder_SetAuthSizeAndMode(SAParams_p,
+                                      SAState_p,
+                                      &Auth1Words,
+                                      &Auth2Words);
+    if (Rc != SAB_STATUS_OK)
+    {
+        return  Rc;
+    }
+
+    /* Now copy the authentication keys, if applicable */
+    if (SAParams_p->AuthAlgo == SAB_AUTH_AES_CCM)
+    {
+        SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+        SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 32);
+        /* Fill zero blocks for the XCBC MAC subkeys */
+        SAState_p->CurrentOffset += 8;
+        SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
+                                    SAParams_p->Key_p,
+                                    SAParams_p->KeyByteCount);
+        SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+
+        if (SAState_p->CipherKeyWords == 6)
+        {
+            SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
+            SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CCM-192*/
+        }
+    }
+    else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_XCBC_MAC ||
+             SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_128 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_192 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_256)
+    {
+#ifdef SAB_STRICT_ARGS_CHECK
+        if (SAParams_p->AuthKey1_p == NULL ||
+            SAParams_p->AuthKey2_p == NULL ||
+            SAParams_p->AuthKey3_p == NULL)
+        {
+            LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+            return SAB_INVALID_PARAMETER;
+        }
+#endif
+        SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+        SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
+                                    SAParams_p->AuthKey2_p,
+                                    4 * sizeof(uint32_t));
+        SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 4,
+                                    SAParams_p->AuthKey3_p,
+                                    4 * sizeof(uint32_t));
+        SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 8,
+                                    SAParams_p->AuthKey1_p,
+                                    Auth1Words * sizeof(uint32_t));
+        SAState_p->CurrentOffset += 8 + Auth1Words;
+        if (Auth1Words == 6)
+        {
+            SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
+            SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CMAC-192*/
+        }
+    }
+#ifdef SAB_ENABLE_AUTH_SHA3
+    else if (SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_224 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_256 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_384 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_512 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_224 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_256 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_384 ||
+             SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_512)
+    {
+#ifdef SAB_STRICT_ARGS_CHECK
+        if (Auth1Words > 0)
+        {
+            if (SAParams_p->AuthKey1_p == NULL &&
+                SAParams_p->AuthKeyByteCount > 0)
+            {
+                LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            if (SAParams_p->AuthKeyByteCount > Auth1Words * sizeof(uint32_t))
+            {
+                LOG_CRIT("SABuilder: Authentication key too long\n");
+                return SAB_INVALID_PARAMETER;
+            }
+#endif
+            SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+            SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+                                  Auth1Words * sizeof(uint32_t));
+
+            SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                    SAParams_p->AuthKey1_p,
+                                    SAParams_p->AuthKeyByteCount);
+
+            SAState_p->CurrentOffset += Auth1Words;
+
+            if (SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
+                SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
+                SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
+                SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512)
+            {
+                if (SAParams_p->AuthKeyByteCount <
+                    Auth1Words * sizeof(uint32_t))
+                {
+                    // Put the key length in last byte of key if it is smaller
+                    // than the maximum.
+                    SAState_p->CW1 |= SAB_CW1_DIGEST_CNT;
+                    if (SABuffer_p != NULL)
+                    {
+                        SABuffer_p[SAState_p->CurrentOffset - 1] |=
+                            (SAParams_p->AuthKeyByteCount << 24);
+                    }
+                }
+            }
+        }
+    }
+#endif
+    else if(Auth1Words > 0 && Auth2Words > 0 &&
+            SAParams_p->AuthKey1_p == NULL && SAParams_p->AuthKey2_p == NULL)
+    {
+        /* HMAC precomputes not given, allow later computation of
+           precomputes. */
+        SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+        SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset + Auth1Words;
+        SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+                              (Auth1Words + Auth2Words) * sizeof(uint32_t));
+        SAState_p->CurrentOffset += Auth1Words + Auth2Words;
+    }
+    else
+    {
+        if (Auth1Words > 0)
+        {
+#ifdef SAB_STRICT_ARGS_CHECK
+            if (SAParams_p->AuthKey1_p == NULL)
+            {
+                LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+                return SAB_INVALID_PARAMETER;
+            }
+#endif
+            SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+            SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                    SAParams_p->AuthKey1_p,
+                                    Auth1Words * sizeof(uint32_t));
+            SAState_p->CurrentOffset += Auth1Words;
+
+            if (SAParams_p->AuthAlgo == SAB_AUTH_SSLMAC_SHA1)
+            { /* both inner and outer digest fields must be set, even though
+                 only one is used. */
+                SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+                                        Auth1Words * sizeof(uint32_t));
+                SAState_p->CurrentOffset += Auth1Words;
+            }
+        }
+        if (Auth2Words > 0)
+        {
+#ifdef SAB_STRICT_ARGS_CHECK
+            if (SAParams_p->AuthKey2_p == NULL)
+            {
+                LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+                return SAB_INVALID_PARAMETER;
+            }
+#endif
+            SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset;
+            SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                    SAParams_p->AuthKey2_p,
+                                    Auth2Words * sizeof(uint32_t));
+            SAState_p->CurrentOffset += Auth2Words;
+        }
+    }
+
+    return SAB_STATUS_OK;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_GetSizes
+ *
+ * Compute the required sizes in 32-bit words of any of up to three memory
+ * areas used by the SA.
+ *
+ * SAParams_p (input)
+ *   Pointer to the SA parameters structure.
+ *
+ * SAWord32Count_p (output)
+ *   The size of the normal SA buffer.
+ *
+ * SAStateWord32Count_p (output)
+ *   The size of any SA state record.
+ *
+ * ARC4StateWord32Count_p (output) T
+ *   The size of any ARCFOUR state buffer (output).
+ *
+ * When the SA state record or ARCFOUR state buffer are not required by
+ * the packet engine for this transform, the corresponding size outputs
+ * are returned as zero. The Security-IP-96 never requires these buffers
+ *
+ * If any of the output parameters is a null pointer,
+ * the corresponding size will not be returned.
+ *
+ * The SAParams_p structure must be fully filled in: it must have the
+ * same contents as it would have when SABuilder_BuildSA is called.
+ * This function calls the same routines as SABuilder_BuildSA, but with
+ * null pointers instead of the SA pointer, so no actual SA will be built.
+ * These functions are only called to obtain the length of the SA.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when the record referenced by SAParams_p is invalid,
+ */
+SABuilder_Status_t
+SABuilder_GetSizes(
+        SABuilder_Params_t *const SAParams_p,
+        unsigned int *const SAWord32Count_p,
+        unsigned int *const SAStateWord32Count_p,
+        unsigned int *const ARC4StateWord32Count_p)
+{
+    SABuilder_State_t SAState;
+    int rc;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL)
+    {
+        LOG_CRIT("SABuilder_GetSizes: NULL pointer SAParams_p supplied\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
+    SAState.CW0 = 0;
+    SAState.CW1 = 0;
+    SAState.CipherKeyWords = 0;
+    SAState.IVWords = 0;
+    SAState.ARC4State = false;
+    SAState.fLarge = false;
+    SAState.fLargeMask = false;
+
+    rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, NULL);
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+    rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, NULL);
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+    switch ( SAParams_p->protocol)
+    {
+#ifdef SAB_ENABLE_PROTO_BASIC
+    case SAB_PROTO_BASIC:
+    {
+        rc = SABuilder_SetBasicParams(SAParams_p, &SAState, NULL);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_IPSEC
+    case SAB_PROTO_IPSEC:
+    {
+        rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, NULL);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+    case SAB_PROTO_SSLTLS:
+    {
+        rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, NULL);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SRTP
+    case SAB_PROTO_SRTP:
+    {
+        rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, NULL);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_MACSEC
+    case SAB_PROTO_MACSEC:
+    {
+        rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, NULL);
+    }
+    break;
+#endif
+    default:
+        LOG_CRIT("SABuilder_GetSizes: unsupported protocol\n");
+        return SAB_INVALID_PARAMETER;
+    }
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+    if (SAState.ARC4State)
+    {
+        SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
+    }
+
+    if (SAState.CurrentOffset == 2)
+    {
+        SAState.CurrentOffset += 1;
+        /* Make sure to have at least one non-context word */
+    }
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+    /* It is possible that a record will have to be
+       large because of options used by firmware, so determine if the record
+       needs to be large. */
+    if (SAParams_p->protocol == SAB_PROTO_IPSEC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedIPsecParams(SAParams_p,
+                                               &SAState,
+                                               NULL);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, NULL);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_MACSEC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedMACsecParams(SAParams_p,
+                                                &SAState,
+                                                NULL);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_BASIC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedBasicParams(SAParams_p,
+                                               &SAState,
+                                               NULL);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+    if (SAParams_p->OffsetSeqNum <= SAB_SEQNUM_LO_FIX_OFFSET &&
+        !SAState.fLarge)
+    {
+        SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+    }
+    else if (SAState.CurrentOffset <= SAB_RECORD_WORD_COUNT + LargeTransformOffset)
+    {
+        SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+    }
+    else
+    {
+        LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#else
+    if (SAState.CurrentOffset > SAB_RECORD_WORD_COUNT)
+    {
+        LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+    SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+    /* Make the SA record a fixed size for engines that have
+       record caches */
+#endif
+#endif
+
+    if (SAStateWord32Count_p != NULL)
+        *SAStateWord32Count_p = 0;
+
+#ifdef SAB_ARC4_STATE_IN_SA
+    if (ARC4StateWord32Count_p != NULL)
+        *ARC4StateWord32Count_p = 0;
+    if (SAState.ARC4State)
+    {
+        if (SAParams_p->OffsetARC4StateRecord > 0)
+        {
+            if (SAParams_p->OffsetARC4StateRecord  < SAState.CurrentOffset)
+            {
+                LOG_CRIT("SABuilder_GetSizes: OffsetARC4StateRecord too low\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            SAState.CurrentOffset = SAParams_p->OffsetARC4StateRecord + 64;
+        }
+        else
+        {
+            SAState.CurrentOffset =
+                    SABuilder_AlignForARc4State(SAState.CurrentOffset);
+            SAState.CurrentOffset += 64;
+        }
+    }
+#else
+    if (ARC4StateWord32Count_p != NULL)
+    {
+        if (SAState.ARC4State)
+        {
+            *ARC4StateWord32Count_p = 64;
+        }
+        else
+        {
+            *ARC4StateWord32Count_p = 0;
+        }
+    }
+#endif
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+    {
+        TokenBuilder_Status_t rc;
+        unsigned int ContextSize;
+        rc = TokenBuilder_GetContextSize(SAParams_p, &ContextSize);
+        if (rc != TKB_STATUS_OK)
+        {
+            return SAB_ERROR;
+        }
+        SAState.CurrentOffset += ContextSize;
+    }
+#endif
+    if (SAWord32Count_p != NULL)
+        *SAWord32Count_p = SAState.CurrentOffset;
+
+    return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_BuildSA
+ *
+ * Construct the SA record for the operation described in SAParams_p in
+ * up to three memory buffers.
+ *
+ * SAParams_p (input)
+ *    Pointer to the SA parameters structure.
+ *
+ * SABuffer_p (output)
+ *    Pointer to the the normal SA buffer.
+ *
+ * SAStateBuffer_p (output)
+ *    Pointer to the SA state record buffer.
+ *
+ * ARC4StateBuffer_p (output)
+ *    Pointer to the ARCFOUR state buffer.
+ *
+ * Each of the Buffer arguments must point to a word-aligned
+ * memory buffer whose size in words is at least equal to the
+ * corresponding size parameter returned by SABuilder_GetSizes().
+ *
+ * If any of the three buffers is not required for the SA (the
+ * corresponding size in SABuilder_GetSizes() is 0), the corresponding
+ * Buffer arguments to this function may be a null pointer.
+ * The Security-IP-96 never requires these buffers.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_BuildSA(
+        SABuilder_Params_t * const SAParams_p,
+        uint32_t *const SABuffer_p,
+        uint32_t *const SAStateBuffer_p,
+        uint32_t *const ARC4StateBuffer_p)
+{
+    SABuilder_State_t SAState;
+    int rc;
+
+    IDENTIFIER_NOT_USED(SAStateBuffer_p);
+    IDENTIFIER_NOT_USED(ARC4StateBuffer_p);
+
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SABuffer_p == NULL)
+    {
+        LOG_CRIT("SABuilder: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
+    SAState.CW0 = 0;
+    SAState.CW1 = 0;
+    SAState.CipherKeyWords = 0;
+    SAState.IVWords = 0;
+    SAState.ARC4State = false;
+    SAState.fLarge = false;
+    SAState.fLargeMask = false;
+
+    rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, SABuffer_p);
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+    rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, SABuffer_p);
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+    switch ( SAParams_p->protocol)
+    {
+#ifdef SAB_ENABLE_PROTO_BASIC
+    case SAB_PROTO_BASIC:
+    {
+        rc = SABuilder_SetBasicParams(SAParams_p, &SAState, SABuffer_p);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_IPSEC
+    case SAB_PROTO_IPSEC:
+    {
+        rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, SABuffer_p);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+    case SAB_PROTO_SSLTLS:
+    {
+        rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, SABuffer_p);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SRTP
+    case SAB_PROTO_SRTP:
+    {
+        rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, SABuffer_p);
+    }
+    break;
+#endif
+#ifdef SAB_ENABLE_PROTO_MACSEC
+    case SAB_PROTO_MACSEC:
+    {
+        rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, SABuffer_p);
+    }
+    break;
+#endif
+    default:
+        LOG_CRIT("SABuilder_BuildSA: unsupported protocol\n");
+        return SAB_UNSUPPORTED_FEATURE;
+    }
+    if (rc != SAB_STATUS_OK)
+        return rc;
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+    if (SAParams_p->OffsetSeqNum > SAB_SEQNUM_LO_FIX_OFFSET)
+        SAState.fLarge = true;
+#endif
+#endif
+
+    if (SAState.ARC4State)
+    {
+        unsigned int ARC4Offset = 0;
+#ifdef SAB_ARC4_STATE_IN_SA
+        if (SAParams_p->OffsetARC4StateRecord > 0)
+        {
+            ARC4Offset = SAParams_p->OffsetARC4StateRecord;
+        }
+        else
+        {
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+            if (SAState.fLarge)
+            {
+                ARC4Offset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+            }
+            else
+#else
+            {
+                ARC4Offset = SAB_RECORD_WORD_COUNT;
+            }
+#endif
+#else
+            ARC4Offset = SAState.CurrentOffset + 2;
+#endif
+            ARC4Offset = SABuilder_AlignForARc4State(ARC4Offset);
+        }
+#endif
+        SABuffer_p[SAState.CurrentOffset] = ARC4Offset * sizeof(uint32_t);
+        SABuffer_p[SAState.CurrentOffset + 1] = 0;
+
+        if ( (SAParams_p->flags & SAB_FLAG_ARC4_STATE_LOAD) != 0)
+        {
+            /* Load the ARC4 state when building the SA.
+             Nonce_p[0] is the 'i' variable and
+             Nonce_p[1] is the 'j' variable.
+             IV_p points to the 256-byte state array.
+             The SA Builder will not fill in the ARC4 state pointer. */
+            if (SAParams_p->Nonce_p != NULL)
+            {
+                SABuffer_p[SAState.CurrentOffset + 1] =
+                    ((SAParams_p->Nonce_p[0] + 1) & 0xff) |
+                    (SAParams_p->Nonce_p[1]<<8);
+            }
+            if(SAParams_p->IV_p != NULL)
+            {
+#ifdef SAB_ARC4_STATE_IN_SA
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        (SAParams_p->OffsetARC4StateRecord >0 ?
+                                         SAParams_p->OffsetARC4StateRecord :
+                                          ARC4Offset),
+                                        SAParams_p->IV_p,
+                                        256);
+
+#else
+                SABuilderLib_CopyKeyMat(ARC4StateBuffer_p,
+                                        0,
+                                        SAParams_p->IV_p,
+                                        256);
+#endif
+            }
+
+        }
+
+        SAParams_p->OffsetIJPtr = SAState.CurrentOffset + 1;
+        SAParams_p->OffsetARC4State = SAState.CurrentOffset;
+
+        SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
+    }
+
+    if (SAState.CurrentOffset == 2)
+    {
+        SABuffer_p[SAState.CurrentOffset++] = 0;
+        /* Make sure to have at least one non-context word */
+    }
+
+    if (!SAState.fLargeMask)
+        SAState.CW0 |= (SAState.CurrentOffset - 2) << 8;
+    else
+        SAState.CW0 |= (SAState.CurrentOffset == 66)? 0x0200 : 0x0300;
+
+    SABuffer_p[0] = SAState.CW0;
+    SABuffer_p[1] = SAState.CW1;
+
+    SAParams_p->CW0 = SAState.CW0;
+    SAParams_p->CW1 = SAState.CW1;
+
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_IPSEC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedIPsecParams(SAParams_p,
+                                               &SAState,
+                                               SABuffer_p);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, SABuffer_p);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_MACSEC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedMACsecParams(SAParams_p,
+                                                &SAState,
+                                                SABuffer_p);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+    if (SAParams_p->protocol == SAB_PROTO_BASIC)
+    {
+        SABuilder_Status_t res;
+        res = SABuilder_SetExtendedBasicParams(SAParams_p,
+                                               &SAState,
+                                               SABuffer_p);
+        if (res != SAB_STATUS_OK)
+            return res;
+    }
+#endif
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+    if (SAState.fLarge)
+    {
+        SABuffer_p[0] |= SAB_CW0_SW_IS_LARGE;
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+        /* Must be set independent of protocol */
+        if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+                       LargeTransformOffset] |=
+                BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
+        }
+#endif
+        SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+    }
+    else
+    {
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+        /* Must be set independent of protocol */
+        if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] |=
+                BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
+        }
+#endif
+        SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+    }
+#endif
+#endif
+
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+    {
+        TokenBuilder_Status_t rc;
+        void *TokenContext_p = (void*)&SABuffer_p[SAState.CurrentOffset];
+        rc = TokenBuilder_BuildContext(SAParams_p, TokenContext_p);
+        if (rc != TKB_STATUS_OK)
+        {
+            return SAB_ERROR;
+        }
+    }
+#endif
+
+
+    return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetLargeTransformOffset();
+ */
+SABuilder_Status_t
+SABuilder_SetLargeTransformOffset(
+    unsigned int Offset)
+{
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
+    LargeTransformOffset = Offset;
+    return SAB_STATUS_OK;
+#else
+    IDENTIFIER_NOT_USED(Offset);
+    return SAB_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/* end of file sa_builder.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c
new file mode 100644
index 0000000..256e341
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c
@@ -0,0 +1,444 @@
+/* sa_builder_basic.c
+ *
+ * Basic Crypto/hash specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the Basic Crypto/hash
+ * specific part of an SA).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_basic.h"
+#include "sa_builder_internal.h" /* SABuilder_SetBasicParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_BASIC
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_Basic
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_Basic_t extension with sensible defaults for
+ * basic crypto and hash processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ *
+ * SAParamsBasic_p (output)
+ *   Pointer to Basic parameter extension to be filled in
+ *
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. Either the cipher algorithm or the authentication algorithm
+ * or both can be set to one of the supported algorithms for
+ * basic crypto or basic hash or HMAC. If they are both left at NULL. the
+ * SA will be a bypass SA. The crypto mode and IV source
+ * can be specified as well.  Any required keys have to be specified
+ * as well.
+ *
+ * Both the SAParams_p and SAParamsBasic_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsBasic_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_Basic(
+        SABuilder_Params_t * const SAParams_p,
+        SABuilder_Params_Basic_t * const SAParamsBasic_p,
+        const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SAParamsBasic_p == NULL)
+    {
+        LOG_CRIT("SABuilder_Init_Basic: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (direction != SAB_DIRECTION_OUTBOUND &&
+        direction != SAB_DIRECTION_INBOUND)
+    {
+        LOG_CRIT("SABuilder_Init_Basic: Invalid direction.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAParams_p->protocol = SAB_PROTO_BASIC;
+    SAParams_p->direction = direction;
+    SAParams_p->ProtocolExtension_p = (void*)SAParamsBasic_p;
+    SAParams_p->flags = 0;
+    SAParams_p->RedirectInterface = 0;
+
+    SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+    SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+    SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+    SAParams_p->CryptoParameter = 0;
+    SAParams_p->KeyByteCount = 0;
+    SAParams_p->Key_p = NULL;
+    SAParams_p->IV_p = NULL;
+    SAParams_p->Nonce_p = NULL;
+
+    SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+    SAParams_p->AuthKey1_p = NULL;
+    SAParams_p->AuthKey2_p = NULL;
+    SAParams_p->AuthKey3_p = NULL;
+    SAParams_p->AuthKeyByteCount = 0;
+
+    SAParams_p->OffsetARC4StateRecord = 0;
+    SAParams_p->CW0 = 0;
+    SAParams_p->CW1 = 0;
+    SAParams_p->OffsetDigest0 = 0;
+    SAParams_p->OffsetDigest1 = 0;
+    SAParams_p->OffsetSeqNum = 0;
+    SAParams_p->OffsetSeqMask = 0;
+    SAParams_p->OffsetIV = 0;
+    SAParams_p->OffsetIJPtr = 0;
+    SAParams_p->OffsetARC4State = 0;
+    SAParams_p->SeqNumWord32Count = 0;
+    SAParams_p->SeqMaskWord32Count = 0;
+    SAParams_p->IVWord32Count = 0;
+
+    SAParamsBasic_p->BasicFlags = 0;
+    SAParamsBasic_p->DigestBlockCount = 0;
+    SAParamsBasic_p->ICVByteCount = 0;
+
+    SAParamsBasic_p->fresh = 0;
+    SAParamsBasic_p->bearer = 0;
+    SAParamsBasic_p->direction = 0;
+
+    SAParamsBasic_p->ContextRef = 0;
+    return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetBasicParams
+ *
+ * Fill in Basic Crypto and hash-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetBasicParams(
+        SABuilder_Params_t *const SAParams_p,
+        SABuilder_State_t * const SAState_p,
+        uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_Basic_t *SAParamsBasic_p;
+    SAParamsBasic_p = (SABuilder_Params_Basic_t *)
+        (SAParams_p->ProtocolExtension_p);
+
+    if (SAParamsBasic_p == NULL)
+    {
+        LOG_CRIT("SABuilder: Basic extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (SAParamsBasic_p->direction > 1 ||
+        SAParamsBasic_p->bearer > 32)
+    {
+        LOG_CRIT("SABuilder: Illegal value for bearer or direction\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Use one of the classic hash algorithms, possibly with
+       encryption */
+    if ((SAParams_p->AuthAlgo == SAB_AUTH_HASH_MD5 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA1 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_224 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_256 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_384 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_512 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_HASH_SM3) &&
+        (SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+                              SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+    {
+        /* We are doing basic hash (no HMAC) with storing the state.*/
+        SAState_p->CW1 |= SAB_CW1_HASH_STORE | SAB_CW1_DIGEST_CNT;
+        if(SABuffer_p != NULL)
+            SABuffer_p[SAState_p->CurrentOffset] =
+                SAParamsBasic_p->DigestBlockCount;
+        SAState_p->CurrentOffset += 1;
+    }
+    else if (SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+             (SAParams_p->flags & (SAB_FLAG_HASH_SAVE)) != 0)
+    {
+        SAState_p->CW1 |= SAB_CW1_HASH_STORE;
+    }
+
+    if ((SAParams_p->AuthAlgo == SAB_AUTH_KASUMI_F9 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_SNOW_UIA2 ||
+         SAParams_p->AuthAlgo == SAB_AUTH_ZUC_EIA3) &&
+        SAParamsBasic_p->direction != 0)
+    {
+        SAState_p->CW1 |= SAB_CW1_WIRELESS_DIR;
+    }
+
+    if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {
+        /* We are now doing basic encryption/decryption,
+           possibly with hash.*/
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+                SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT;
+            else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM ||
+                     SAParams_p->AuthAlgo==SAB_AUTH_AES_GMAC)
+                SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+            else if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+                SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+            else
+                SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+        else
+            if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+                SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT;
+            else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM)
+                SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+            else if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+            {
+                SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+                SAState_p->CW1 |= SAB_CW1_PREPKT_OP;
+                SAState_p->CW1 |= SAB_CW1_PAD_TLS;
+            }
+            else
+                SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+        /* Check for prohibited algorithms and crypto modes. */
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CFB1 ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CFB8)
+        {
+            LOG_CRIT("SABuilder: crypto algorithm/mode not supported\n");
+            return SAB_INVALID_PARAMETER;
+        }
+
+        /* Reject crypto modes other than CBC for ENCRYPT_AFTER_HASH */
+        if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0 &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC)
+        {
+            LOG_CRIT("SABuilder: crypto algorithm/mode not supported for encrypt after hash\n");
+            return SAB_INVALID_PARAMETER;
+        }
+
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS_STATEFUL)
+        { /* For AES-XTS, extract Key2 from Nonce_p parameter,
+           same size as the primary AES key. */
+#ifdef SAB_STRICT_ARGS_CHECK
+            if (SAParams_p->Nonce_p == NULL)
+            {
+                LOG_CRIT("SABuilder: NULL pointer Key 2.\n");
+                return SAB_INVALID_PARAMETER;
+            }
+#endif
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    SAState_p->CurrentOffset,
+                                    SAParams_p->Nonce_p,
+                                    SAParams_p->KeyByteCount);
+            SAState_p->CurrentOffset+=SAState_p->CipherKeyWords;
+        }
+
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_F8 ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_UEA2 ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_EEA3)
+        {
+            SAParams_p->IVSrc = SAB_IV_SRC_TOKEN;
+        }
+        else if (SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+                 SAParams_p->CryptoMode != SAB_CRYPTO_MODE_ECB &&
+                 !(SAParams_p->CryptoAlgo==SAB_CRYPTO_KASUMI &&
+                   SAParams_p->CryptoMode==SAB_CRYPTO_MODE_BASIC))
+        {
+            /* For ARCFOUR and block ciphers in ECB mode and
+               Basic Kasumi we do not have an IV */
+            if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+                SAParams_p->IVSrc = SAB_IV_SRC_INPUT;
+
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+                SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM ||
+                SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+                SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+            {
+                if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+                {
+                    SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR);
+                    SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+                    /* When the CTR mode IV is loaded from token, then
+                       load all four IV words, including block counter */
+                }
+                else
+                {   /* else add nonce to SA */
+                    SAState_p->CW1 |= SAB_CW1_IV0;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+                    if (SAParams_p->Nonce_p == NULL)
+                    {
+                        LOG_CRIT("SABuilder: NULL pointer nonce.\n");
+                        return SAB_INVALID_PARAMETER;
+                    }
+#endif
+                    if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+                    {
+                        if (SABuffer_p != NULL)
+                            SABuffer_p[SAState_p->CurrentOffset] =
+                              (SAParams_p->Nonce_p[0] << 8)  |
+                              (SAParams_p->Nonce_p[1] << 16) |
+                              (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+                    }
+                    else
+                    {
+                        SABuilderLib_CopyKeyMat(SABuffer_p,
+                                                SAState_p->CurrentOffset,
+                                                SAParams_p->Nonce_p, sizeof(uint32_t));
+                    }
+                    SAState_p->CurrentOffset +=1;
+                }
+
+                if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+                {
+                    SAState_p->CW1 |= SAB_CW1_IV_CTR |
+                                      SAB_CW1_IV1    |
+                                      SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+                    if (SAParams_p->IV_p == NULL)
+                    {
+                        LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                        return SAB_INVALID_PARAMETER;
+                    }
+#endif
+                    SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                    SAParams_p->IVWord32Count = 2;
+
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->IV_p, 8);
+                    SAState_p->CurrentOffset += 2;
+                }
+                else
+                {
+                    SAState_p->CW1 |= SAB_CW1_IV_CTR;
+                }
+
+                if (SAParams_p->IVSrc != SAB_IV_SRC_TOKEN &&
+                    SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+                {
+                    /* Add 0 counter field (IV3) */
+                    SAState_p->CW1 |= SAB_CW1_IV3;
+                    if(SABuffer_p != NULL)
+                        SABuffer_p[SAState_p->CurrentOffset] = 0;
+                    SAState_p->CurrentOffset+=1;
+                }
+            }
+            else
+            {
+                if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ICM)
+                {
+                    SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR or ICM);
+                    SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+                    /* When the CTR mode IV is loaded from token, then
+                       load all four IV words, including block counter */
+                }
+
+                SAState_p->CW1 |= SAB_CW1_IV_FULL;
+                if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+                {
+                    SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+                    if(SAState_p->IVWords == 4)
+                        SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+                    if (SAParams_p->IV_p == NULL)
+                    {
+                        LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                        return SAB_INVALID_PARAMETER;
+                    }
+#endif
+                    SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                    SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                     SAState_p->CurrentOffset,
+                                     SAParams_p->IV_p,
+                                     SAState_p->IVWords * sizeof(uint32_t));
+                    SAState_p->CurrentOffset += SAState_p->IVWords;
+                    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_DES ||
+                        SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES ||
+                        SAParams_p->CryptoAlgo == SAB_CRYPTO_AES ||
+                        SAParams_p->CryptoAlgo == SAB_CRYPTO_SM4 ||
+                        SAParams_p->CryptoAlgo == SAB_CRYPTO_BC0)
+                      SAState_p->CW1 |= SAB_CW1_CRYPTO_STORE;
+                }
+            }
+        }
+    }
+    else
+    {
+        /* Bypass operation or authenticate-only,
+           use inbound direction when verifying */
+        if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_NULL_OUT;
+        else if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_EXTRACT_ICV) !=0)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+    }
+
+    return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_PROTO_BASIC */
+
+/* end of file sa_builder_basic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c
new file mode 100644
index 0000000..236a8ba
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c
@@ -0,0 +1,406 @@
+/* sa_builder_extended_basic.c
+ *
+ * Basic opaeration specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the Basic specific
+ * part of an SA) in the Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetBasicParams */
+#include "sa_builder_basic.h"
+
+#include "firmware_eip207_api_cs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedBasicParams
+ *
+ * Fill in Basic-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedBasicParams(SABuilder_Params_t *const SAParams_p,
+                                 SABuilder_State_t * const SAState_p,
+                                 uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_Basic_t *SAParamsBasic_p =
+        (SABuilder_Params_Basic_t *)(SAParams_p->ProtocolExtension_p);
+
+    IDENTIFIER_NOT_USED(SAState_p);
+
+#ifdef FIRMWARE_EIP207_CS_TR_IV_WORD_OFFSET
+    /* These operations are specific to PDCP firmware */
+    if (SAParams_p->AuthAlgo == SAB_AUTH_SNOW_UIA2 ||
+        SAParams_p->AuthAlgo == SAB_AUTH_KASUMI_F9)
+    {
+        if(SABuffer_p != NULL)
+            SABuffer_p[FIRMWARE_EIP207_CS_TR_IV_WORD_OFFSET] =
+                SAParamsBasic_p->fresh;
+    }
+#endif
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET
+    /* These operations are specific to non-PDCP firmware */
+    if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+         SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+         SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+         SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC &&
+         SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM) ||
+        (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL &&
+         SAParams_p->AuthAlgo == SAB_AUTH_NULL))
+    {
+        /* Only combined crypto + hash and not AES-GCM/AES-GMAC/AES-CCM are
+           supported */
+        uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+        SABuilder_ESPProtocol_t ESPProto;
+        SABuilder_HeaderProtocol_t HeaderProto;
+        uint8_t PadBlockByteCount = 1;
+        uint8_t IVByteCount = 0;
+        uint8_t ICVByteCount = 0;
+        uint32_t flags = 0;
+        uint32_t VerifyInstructionWord, CtxInstructionWord;
+        uint32_t IVInstructionWord = 0;
+
+        if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+        {
+            ESPProto = SAB_ESP_PROTO_NONE;
+            if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_XFRM_API) != 0)
+
+                HeaderProto = SAB_HDR_BASIC_IN_NO_PAD;
+            else
+                HeaderProto = SAB_HDR_BYPASS;
+            VerifyInstructionWord = SAB_VERIFY_NONE;
+        }
+        else
+        {
+            if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+            {
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                {
+                    ESPProto = SAB_BASIC_PROTO_OUT_HASHENC;
+                    HeaderProto = SAB_HDR_BASIC_OUT_TPAD;
+                }
+                else
+                {
+                    ESPProto = SAB_BASIC_PROTO_IN_DECHASH;
+                    TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+                    HeaderProto = SAB_HDR_BASIC_IN_PAD;
+                }
+            }
+            else
+            {
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                {
+                    ESPProto = SAB_BASIC_PROTO_OUT_ENCHASH;
+                    HeaderProto = SAB_HDR_BASIC_OUT_ZPAD;
+                }
+                else
+                {
+                    ESPProto = SAB_BASIC_PROTO_IN_HASHDEC;
+                    HeaderProto = SAB_HDR_BASIC_IN_NO_PAD;
+                }
+        }
+
+            if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_HEADER) == 0)
+                flags |= BIT_29;
+
+            switch(SAParams_p->CryptoAlgo)
+            {
+            case SAB_CRYPTO_DES:
+            case SAB_CRYPTO_3DES:
+                IVByteCount = 8;
+                PadBlockByteCount = 8;
+            break;
+            case SAB_CRYPTO_AES:
+            case SAB_CRYPTO_SM4:
+            case SAB_CRYPTO_BC0:
+                IVByteCount = 16;
+                PadBlockByteCount = 16;
+                break;
+            default:
+                LOG_CRIT("SABuilder_BuildSA: unsupported crypto algorithm\n");
+                return SAB_UNSUPPORTED_FEATURE;
+            }
+
+            switch(SAParams_p->CryptoMode)
+            {
+            case SAB_CRYPTO_MODE_ECB:
+                IVByteCount = 0;
+                IVInstructionWord = 0x20000004; /* NOP instruction */
+                break;
+            case SAB_CRYPTO_MODE_CBC:
+                if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+                    SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+                {
+                    IVInstructionWord = SA_RETR_HASH_IV0 + IVByteCount;
+                }
+                else
+                {
+                    IVInstructionWord = SA_INS_NONE_IV0 + IVByteCount;
+                    IVByteCount = 0;
+                }
+                if (SAParams_p->IVSrc == SAB_IV_SRC_PRNG)
+                    TokenHeaderWord |= SAB_HEADER_IV_PRNG;
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                {
+                    IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+                }
+                if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+                {
+                    IVInstructionWord &= ~BIT_25; /* Do not hash IV for HASHENC */
+                }
+                break;
+            case SAB_CRYPTO_MODE_CTR:
+                IVByteCount = 8;
+                PadBlockByteCount = 1;
+                if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+                    SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+                {
+                    IVInstructionWord = SA_RETR_HASH_IV1 + IVByteCount;
+                }
+                else
+                {
+                    IVInstructionWord = SA_INS_NONE_IV1 + IVByteCount;
+                    IVByteCount = 0;
+                }
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                {
+                    IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+                }
+                break;
+            case SAB_CRYPTO_MODE_ICM:
+                IVByteCount = 16;
+                PadBlockByteCount = 1;
+                if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+                    SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+                {
+                    IVInstructionWord = SA_RETR_HASH_IV0 + IVByteCount;
+                }
+                else
+                {
+                    IVInstructionWord = SA_INS_NONE_IV0 + IVByteCount;
+                    IVByteCount = 0;
+                }
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                {
+                    IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+                }
+                break;
+            default:
+                LOG_CRIT("SABuilder_BuildSA: unsupported crypto mode\n");
+                return SAB_UNSUPPORTED_FEATURE;
+            }
+
+            switch(SAParams_p->AuthAlgo)
+            {
+            case SAB_AUTH_HASH_MD5:
+            case SAB_AUTH_SSLMAC_MD5:
+            case SAB_AUTH_HMAC_MD5:
+                ICVByteCount = 16;
+                break;
+            case SAB_AUTH_HASH_SHA1:
+            case SAB_AUTH_SSLMAC_SHA1:
+            case SAB_AUTH_HMAC_SHA1:
+                ICVByteCount = 20;
+                break;
+            case SAB_AUTH_HASH_SHA3_224:
+            case SAB_AUTH_KEYED_HASH_SHA3_224:
+            case SAB_AUTH_HMAC_SHA3_224:
+                ICVByteCount = 28;
+                break;
+            case SAB_AUTH_HASH_SHA2_224:
+            case SAB_AUTH_HMAC_SHA2_224:
+            case SAB_AUTH_HASH_SHA2_256:
+            case SAB_AUTH_HMAC_SHA2_256:
+            case SAB_AUTH_HMAC_SM3:
+            case SAB_AUTH_HASH_SM3:
+            case SAB_AUTH_HASH_SHA3_256:
+            case SAB_AUTH_KEYED_HASH_SHA3_256:
+            case SAB_AUTH_HMAC_SHA3_256:
+                ICVByteCount = 32;
+                break;
+            case SAB_AUTH_HASH_SHA3_384:
+            case SAB_AUTH_KEYED_HASH_SHA3_384:
+            case SAB_AUTH_HMAC_SHA3_384:
+                ICVByteCount = 48;
+                break;
+            case SAB_AUTH_HASH_SHA2_384:
+            case SAB_AUTH_HMAC_SHA2_384:
+                if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+                    ICVByteCount = 48;
+                else
+                    ICVByteCount = 64;
+                break;
+            case SAB_AUTH_HASH_SHA3_512:
+            case SAB_AUTH_KEYED_HASH_SHA3_512:
+            case SAB_AUTH_HMAC_SHA3_512:
+            case SAB_AUTH_HASH_SHA2_512:
+            case SAB_AUTH_HMAC_SHA2_512:
+                ICVByteCount = 64;
+                break;
+            case SAB_AUTH_AES_XCBC_MAC:
+            case SAB_AUTH_AES_CMAC_128:
+            case SAB_AUTH_AES_CMAC_192:
+            case SAB_AUTH_AES_CMAC_256:
+                ICVByteCount = 16;
+                break;
+            default:
+                LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+                return SAB_UNSUPPORTED_FEATURE;
+            }
+            if (SAParamsBasic_p->ICVByteCount != 0 &&
+                SAParamsBasic_p->ICVByteCount < ICVByteCount)
+                ICVByteCount = SAParamsBasic_p->ICVByteCount;
+
+            /* Take care of the VERIFY and CTX token instructions */
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                VerifyInstructionWord = SAB_VERIFY_NONE;
+            }
+            else
+            {
+                if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+                {
+                    VerifyInstructionWord = SAB_VERIFY_PAD;
+                }
+                else
+                {
+                    VerifyInstructionWord = SAB_VERIFY_NONE;
+                }
+                VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+            }
+        }
+
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+        if (SAState_p->fLarge)
+        {
+            CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+        }
+        else
+#endif
+        {
+            CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+        }
+
+        /* Write all parameters to their respective offsets */
+        if (SABuffer_p != NULL)
+        {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+            if (SAState_p->fLarge)
+            {
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+                           LargeTransformOffset] = flags;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+                    LargeTransformOffset] = SAParamsBasic_p->ContextRef;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+                           LargeTransformOffset] =
+                    SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+                           LargeTransformOffset] = TokenHeaderWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+                           LargeTransformOffset] =
+                    SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+                    LargeTransformOffset] =IVInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+                    LargeTransformOffset] = VerifyInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+                    LargeTransformOffset] = CtxInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+                           LargeTransformOffset] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+                    LargeTransformOffset] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+                    LargeTransformOffset] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+                    LargeTransformOffset] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+                    LargeTransformOffset] = 0;
+            }
+            else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+            {
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+                    SAParamsBasic_p->ContextRef;
+;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+                    SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+                    SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = IVInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+                    VerifyInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+                    CtxInstructionWord;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+            }
+        }
+    }
+#endif
+    return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_BASIC_EXTENDED */
+
+
+/* end of file sa_builder_extended_basic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c
new file mode 100644
index 0000000..11abdd6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c
@@ -0,0 +1,396 @@
+/* sa_builder_extended_dtls.c
+ *
+ * DTLS specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the DTLS specifc part of an SA.) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetDTLSParams */
+#include "sa_builder_ssltls.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedDTLSParams
+ *
+ * Fill in DTLS-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedDTLSParams(SABuilder_Params_t *const SAParams_p,
+                         SABuilder_State_t * const SAState_p,
+                         uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p =
+        (SABuilder_Params_SSLTLS_t *)(SAParams_p->ProtocolExtension_p);
+    uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+    SABuilder_ESPProtocol_t ESPProto;
+    SABuilder_HeaderProtocol_t HeaderProto;
+    uint8_t PadBlockByteCount;
+    uint8_t IVByteCount;
+    uint8_t ICVByteCount;
+    uint8_t SeqOffset;
+    uint8_t AntiReplay;
+    uint32_t flags = 0;
+    uint32_t VerifyInstructionWord, CtxInstructionWord;
+
+    IDENTIFIER_NOT_USED(SAState_p);
+
+    if (SAParamsSSLTLS_p == NULL)
+    {
+        LOG_CRIT("SABuilder: SSLTLS extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if ((SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_0 &&
+         SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2) ||
+        (SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL))
+    {
+        if (SABuffer_p != 0)
+            LOG_CRIT("SABuilder: SSLTLS record only for look-aside\n");
+        // No extended transform record can be created, however it can
+        // still be valid for host look-aside.
+        return SAB_STATUS_OK;
+    }
+
+    if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_NO_ANTI_REPLAY) != 0)
+        AntiReplay = 0;
+    else
+        AntiReplay = 1;
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+        {
+            ESPProto = SAB_DTLS_PROTO_OUT_CHACHAPOLY;
+            PadBlockByteCount = 0;
+            IVByteCount = 0;
+        }
+        else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+        {
+            ESPProto = SAB_DTLS_PROTO_OUT_GCM;
+            PadBlockByteCount = 0;
+            IVByteCount = 8;
+        }
+        else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+        {
+            ESPProto = SAB_DTLS_PROTO_OUT_CHACHAPOLY;
+            PadBlockByteCount = 0;
+            IVByteCount = 0;
+        }
+        else
+        {
+            switch (SAParams_p->IVSrc)
+            {
+            case SAB_IV_SRC_DEFAULT:
+            case SAB_IV_SRC_PRNG:
+                TokenHeaderWord |=
+                    SAB_HEADER_IV_PRNG;
+                break;
+            case SAB_IV_SRC_SA: /* No action required */
+            case SAB_IV_SRC_TOKEN:
+                break;
+            default:
+                LOG_CRIT("SABuilder_BuildSA:"
+                         "Unsupported IV source\n");
+                return SAB_INVALID_PARAMETER;
+            }
+            ESPProto = SAB_DTLS_PROTO_OUT_CBC;
+            if (SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES)
+            {
+                PadBlockByteCount = 8;
+                IVByteCount = 8;
+            }
+            else
+            {
+                PadBlockByteCount = 16;
+                IVByteCount = 16;
+            }
+        }
+
+        if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+        {
+            if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+            {
+                HeaderProto = SAB_HDR_IPV6_OUT_DTLS_CAPWAP;
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV6_OUT_DTLS;
+            }
+        }
+        else
+        {
+            if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+            {
+                HeaderProto = SAB_HDR_IPV4_OUT_DTLS_CAPWAP;
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV4_OUT_DTLS;
+            }
+        }
+    }
+    else
+    {
+        if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+        {
+            ESPProto = SAB_DTLS_PROTO_IN_CHACHAPOLY;
+            PadBlockByteCount = 0;
+            IVByteCount = 0;
+        }
+        else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+        {
+            ESPProto = SAB_DTLS_PROTO_IN_GCM;
+            PadBlockByteCount = 0;
+            IVByteCount = 8;
+        }
+        else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+        {
+            ESPProto = SAB_DTLS_PROTO_IN_CHACHAPOLY;
+            PadBlockByteCount = 0;
+            IVByteCount = 0;
+        }
+        else
+        {
+            ESPProto = SAB_DTLS_PROTO_IN_CBC;
+            TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+            if (SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES)
+            {
+                PadBlockByteCount = 8;
+                IVByteCount = 8;
+            }
+            else
+            {
+                PadBlockByteCount = 16;
+                IVByteCount = 16;
+            }
+        }
+
+        if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+        {
+            if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+            {
+                HeaderProto = SAB_HDR_IPV6_IN_DTLS_CAPWAP;
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV6_IN_DTLS;
+            }
+        }
+        else
+        {
+            if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+            {
+                HeaderProto = SAB_HDR_IPV4_IN_DTLS_CAPWAP;
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV4_IN_DTLS;
+            }
+        }
+
+        AntiReplay *= SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+    }
+    SeqOffset = SAParams_p->OffsetSeqNum;
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+        SAParamsSSLTLS_p->PadAlignment >
+        PadBlockByteCount &&
+        SAParamsSSLTLS_p->PadAlignment <= 256)
+        PadBlockByteCount =
+            SAParamsSSLTLS_p->PadAlignment;
+
+    switch(SAParams_p->AuthAlgo)
+    {
+    case SAB_AUTH_HMAC_MD5:
+        ICVByteCount = 16;
+        break;
+    case SAB_AUTH_HMAC_SHA1:
+        ICVByteCount = 20;
+        break;
+    case SAB_AUTH_HMAC_SHA2_256:
+    case SAB_AUTH_HMAC_SM3:
+        ICVByteCount = 32;
+        break;
+    case SAB_AUTH_HMAC_SHA2_384:
+        ICVByteCount = 48;
+        break;
+    case SAB_AUTH_HMAC_SHA2_512:
+        ICVByteCount = 64;
+        break;
+    case SAB_AUTH_AES_GCM:
+        ICVByteCount = 16;
+        break;
+    case SAB_AUTH_POLY1305:
+        ICVByteCount = 16;
+        break;
+    break;
+    default:
+        LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+        return SAB_UNSUPPORTED_FEATURE;
+    }
+
+    /* Flags variable */
+    if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+        flags |= BIT_8;
+    if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_PROCESS_IP_HEADERS) !=0)
+        flags |= BIT_19;
+    if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_PLAINTEXT_HEADERS) !=0)
+        flags |= BIT_29;
+
+    /* Take care of the VERIFY and CTX token instructions */
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        VerifyInstructionWord = SAB_VERIFY_NONE;
+        CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+            ((unsigned int)(2<<24)) + SeqOffset;
+    }
+    else
+    {
+        if (PadBlockByteCount != 0)
+        {
+            VerifyInstructionWord = SAB_VERIFY_PAD;
+        }
+        else
+        {
+            VerifyInstructionWord = SAB_VERIFY_NONE;
+        }
+        if (ICVByteCount > 0)
+        {
+            VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+        }
+        if (AntiReplay > 0)
+        {
+            VerifyInstructionWord += SAB_VERIFY_BIT_SEQ;
+        }
+        CtxInstructionWord = SAB_CTX_SEQNUM +
+            ((unsigned int)(2+AntiReplay)<<24) + SeqOffset;
+    }
+    /* Write all parameters to their respective offsets */
+    if (SABuffer_p != NULL)
+    {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+        if (SAState_p->fLarge)
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+                       LargeTransformOffset] = flags;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+                LargeTransformOffset] = SAParamsSSLTLS_p->ContextRef;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+                       LargeTransformOffset] = TokenHeaderWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+                       LargeTransformOffset] =0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+                       LargeTransformOffset] = VerifyInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+                       LargeTransformOffset] = CtxInstructionWord;
+            SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAParamsSSLTLS_p->version;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+                LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+                LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+                LargeTransformOffset] = 0;
+        }
+        else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+                SAParamsSSLTLS_p->ContextRef;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+                SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+                SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+                VerifyInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+                CtxInstructionWord;
+            SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET] =
+                SAParamsSSLTLS_p->version;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+        }
+    }
+    return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_DTLS_EXTENDED */
+
+
+/* end of file sa_builder_extended_dtls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c
new file mode 100644
index 0000000..14a07ab
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c
@@ -0,0 +1,832 @@
+/* sa_builder_extended_ipsec.c
+ *
+ * IPsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the IPSec specifc part of an SA.) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetIpsecParams */
+#include "sa_builder_ipsec.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#define ESP_HDR_LEN 8
+#define IPV4_HDR_LEN 20
+#define IPV6_HDR_LEN 40
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+/*----------------------------------------------------------------------------
+ * get16
+ *
+ * Read 16-bit value from byte array not changing the byte order.
+ */
+static uint16_t
+get16no(
+        uint8_t *p,
+        unsigned int offs)
+{
+    return (p[offs+1]<<8) | p[offs];
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedIPsecParams(SABuilder_Params_t *const SAParams_p,
+                         SABuilder_State_t * const SAState_p,
+                         uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_IPsec_t *SAParamsIPsec_p =
+        (SABuilder_Params_IPsec_t *)(SAParams_p->ProtocolExtension_p);
+    uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+    SABuilder_ESPProtocol_t ESPProto;
+    SABuilder_HeaderProtocol_t HeaderProto;
+    uint8_t PadBlockByteCount;
+    uint8_t IVByteCount;
+    uint8_t ICVByteCount;
+    uint8_t SeqOffset;
+    uint8_t ExtSeq = 0;
+    uint8_t AntiReplay;
+    uint32_t CCMSalt = 0;
+    uint32_t flags = 0;
+    uint32_t VerifyInstructionWord, CtxInstructionWord;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+    uint32_t MTUDiscount = 0;
+    uint32_t CheckSum = 0;
+#endif
+    IDENTIFIER_NOT_USED(SAState_p);
+
+    if (SAParamsIPsec_p == NULL)
+    {
+        LOG_CRIT("SABuilder: IPsec extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) == 0)
+    {
+        LOG_CRIT("SABuilder: IPsec only supports ESP.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+    {
+        if(SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+           SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM)
+        {
+            LOG_CRIT("SABuilder: IPsec for XFRM only supports CBC and GCM modes.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+        {
+            LOG_CRIT("SABuilder: IPsec for XFRM does not support NATT\n");
+            return SAB_INVALID_PARAMETER;
+        }
+
+    }
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY) != 0)
+        AntiReplay = 0;
+    else
+        AntiReplay = 1;
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            ESPProto = SAB_ESP_PROTO_OUT_XFRM_CBC;
+        else
+            ESPProto = SAB_ESP_PROTO_OUT_CBC;
+        PadBlockByteCount = 4;
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            {
+                    HeaderProto = SAB_HDR_IPV6_OUT_XFRM;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = SAB_HDR_IPV6_OUT_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = SAB_HDR_IPV6_OUT_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV6_OUT_TRANSP_HDRBYPASS;
+            }
+        }
+        else
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            {
+                    HeaderProto = SAB_HDR_IPV4_OUT_XFRM;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = SAB_HDR_IPV4_OUT_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = SAB_HDR_IPV4_OUT_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS;
+            }
+        }
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+            ExtSeq = 1;
+    }
+    else
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            ESPProto = SAB_ESP_PROTO_IN_XFRM_CBC;
+        else
+            ESPProto = SAB_ESP_PROTO_IN_CBC;
+        PadBlockByteCount = 4;
+        TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            {
+                    HeaderProto = SAB_HDR_IPV6_IN_XFRM;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = SAB_HDR_IPV6_IN_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = SAB_HDR_IPV6_IN_TRANSP;
+                    TokenHeaderWord |= SAB_HEADER_UPD_HDR;
+                }
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV6_IN_TRANSP_HDRBYPASS;
+            }
+        }
+        else
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+            {
+                    HeaderProto = SAB_HDR_IPV4_IN_XFRM;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = SAB_HDR_IPV4_IN_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = SAB_HDR_IPV4_IN_TRANSP;
+                    TokenHeaderWord |= SAB_HEADER_UPD_HDR;
+                }
+            }
+            else
+            {
+                HeaderProto = SAB_HDR_IPV4_IN_TRANSP_HDRBYPASS;
+            }
+        }
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+            ExtSeq = 1;
+        AntiReplay *= SAParamsIPsec_p->SequenceMaskBitCount / 32;
+    }
+    SeqOffset = SAParams_p->OffsetSeqNum;
+
+    switch (SAParams_p->CryptoAlgo)
+    {
+    case SAB_CRYPTO_NULL:
+        IVByteCount = 0;
+                break;
+    case SAB_CRYPTO_DES:
+    case SAB_CRYPTO_3DES:
+        IVByteCount = 8;
+        PadBlockByteCount = 8;
+        break;
+    case SAB_CRYPTO_AES:
+    case SAB_CRYPTO_SM4:
+    case SAB_CRYPTO_BC0:
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC)
+        {
+            IVByteCount = 16;
+            PadBlockByteCount = 16;
+        }
+        else
+        {
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                ESPProto = SAB_ESP_PROTO_OUT_CTR;
+            else
+                ESPProto = SAB_ESP_PROTO_IN_CTR;
+
+            if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+                IVByteCount = 0;
+            else
+                IVByteCount = 8;
+        }
+        break;
+    case SAB_CRYPTO_CHACHA20:
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            ESPProto = SAB_ESP_PROTO_OUT_CHACHAPOLY;
+        else
+            ESPProto = SAB_ESP_PROTO_IN_CHACHAPOLY;
+
+        if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+            IVByteCount = 0;
+        else
+            IVByteCount = 8;
+        break;
+    default:
+            LOG_CRIT("SABuilder_BuildSA:"
+                     "Unsupported Crypto algorithm\n");
+            return SAB_INVALID_PARAMETER;
+        ;
+    }
+
+    /* For all inbound and CTR mode outbound packets there is
+       only one supported way to obtain the IV, which is already
+       taken care of. Now handle outbound CBC. */
+    if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+       SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+       SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {
+        switch (SAParams_p->IVSrc)
+        {
+        case SAB_IV_SRC_PRNG:
+            TokenHeaderWord |=
+                SAB_HEADER_IV_PRNG;
+            break;
+        case SAB_IV_SRC_DEFAULT:
+        case SAB_IV_SRC_SA: /* No action required */
+        case SAB_IV_SRC_TOKEN:
+            break;
+        default:
+            LOG_CRIT("SABuilder_BuildSA:"
+                     "Unsupported IV source\n");
+            return SAB_INVALID_PARAMETER;
+        }
+    }
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+        SAParamsIPsec_p->PadAlignment >
+        PadBlockByteCount &&
+        SAParamsIPsec_p->PadAlignment <= 256)
+        PadBlockByteCount =
+            SAParamsIPsec_p->PadAlignment;
+
+    switch(SAParams_p->AuthAlgo)
+    {
+    case SAB_AUTH_NULL:
+        ICVByteCount = 0;
+        ExtSeq = 0;
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            ESPProto = SAB_ESP_PROTO_OUT_NULLAUTH;
+        else
+            ESPProto = SAB_ESP_PROTO_IN_NULLAUTH;
+
+        break;
+            case SAB_AUTH_HMAC_MD5:
+    case SAB_AUTH_HMAC_SHA1:
+    case SAB_AUTH_AES_XCBC_MAC:
+    case SAB_AUTH_AES_CMAC_128:
+        ICVByteCount = 12;
+        break;
+    case SAB_AUTH_HMAC_SHA2_224:
+    case SAB_AUTH_HMAC_SHA2_256:
+    case SAB_AUTH_HMAC_SM3:
+        ICVByteCount = 16;
+        break;
+    case SAB_AUTH_HMAC_SHA2_384:
+        ICVByteCount = 24;
+        break;
+    case SAB_AUTH_HMAC_SHA2_512:
+        ICVByteCount = 32;
+        break;
+    case SAB_AUTH_AES_CCM:
+    case SAB_AUTH_AES_GCM:
+    case SAB_AUTH_AES_GMAC:
+        // All these protocols have a selectable ICV length.
+        if (SAParamsIPsec_p->ICVByteCount == 8 ||
+            SAParamsIPsec_p->ICVByteCount == 12 ||
+            SAParamsIPsec_p->ICVByteCount == 16)
+        {
+            ICVByteCount =
+                        SAParamsIPsec_p->ICVByteCount;
+        }
+        else
+        {
+            ICVByteCount = 16;
+        }
+        switch (SAParams_p->AuthAlgo)
+        {
+            /* These protocols need specialized protocol codes
+               for the token generator.*/
+        case SAB_AUTH_AES_CCM:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                ESPProto = SAB_ESP_PROTO_OUT_CCM;
+            else
+                ESPProto = SAB_ESP_PROTO_IN_CCM;
+
+            CCMSalt =
+                (SAParams_p->Nonce_p[0] << 8) |
+                (SAParams_p->Nonce_p[1] << 16) |
+                (SAParams_p->Nonce_p[2] << 24) |
+                SAB_CCM_FLAG_ADATA_L4 |
+                ((ICVByteCount-2)*4);
+            break;
+        case SAB_AUTH_AES_GCM:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+                    ESPProto = SAB_ESP_PROTO_OUT_XFRM_GCM;
+                else
+                    ESPProto = SAB_ESP_PROTO_OUT_GCM;
+            }
+            else
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+                    ESPProto = SAB_ESP_PROTO_IN_XFRM_GCM;
+                else
+                    ESPProto = SAB_ESP_PROTO_IN_GCM;
+            }
+            break;
+        case SAB_AUTH_AES_GMAC:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                        ESPProto = SAB_ESP_PROTO_OUT_GMAC;
+            else
+                ESPProto = SAB_ESP_PROTO_IN_GMAC;
+            break;
+        default:
+            ;
+        }
+        break;
+    case SAB_AUTH_POLY1305:
+        ICVByteCount = 16;
+        break;
+    default:
+        LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+        return SAB_UNSUPPORTED_FEATURE;
+    }
+
+
+    /* Flags variable */
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+        flags |= BIT_8;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+        flags |= BIT_19;
+    if (ExtSeq !=0)
+        flags |= BIT_29;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_DEC_TTL) != 0)
+        flags |= BIT_27;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_DF) != 0)
+        flags |= BIT_20;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_SET_DF) != 0)
+        flags |= BIT_21;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_REPLACE_DSCP) != 0)
+        flags |= BIT_22;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_ECN) != 0)
+        flags |= BIT_23;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) != 0)
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+            flags |= BIT_25;
+        else
+            flags |= BIT_24;
+    }
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+        {
+            LOG_CRIT("NAT only for transport\n");
+            return SAB_INVALID_PARAMETER;
+        }
+        if (SAParams_p->direction==SAB_DIRECTION_INBOUND &&
+            SAParamsIPsec_p->SequenceMaskBitCount > 128)
+        {
+            if (SAState_p->fLarge && LargeTransformOffset == 16)
+            {
+                LOG_CRIT(
+                    "SABuilder_BuildSA: Inbound NAT cannot be combined with \n"
+                    " anti-replay mask > 128\n and HMAC-SHA384/512\n");
+                return SAB_UNSUPPORTED_FEATURE;
+            }
+            else if (SAParams_p->OffsetSeqNum == SAB_SEQNUM_HI_FIX_OFFSET &&
+                     SAParamsIPsec_p->SequenceMaskBitCount > 384)
+            {
+                LOG_CRIT(
+                    "SABuilder_BuildSA: Inbound NAT cannot be combined with \n"
+                    " anti-replay mask > 384\n and HMAC-SHA384/512\n");
+                return SAB_UNSUPPORTED_FEATURE;
+            }
+            else
+            {
+                SAState_p->fLarge = true;
+            }
+        }
+        flags |= BIT_28;
+    }
+
+    /* Take care of the VERIFY and CTX token instructions */
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        VerifyInstructionWord = SAB_VERIFY_NONE;
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+        {
+            if (SAState_p->fLarge)
+            {
+                CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+            }
+            else
+#endif
+            {
+                CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+            }
+        }
+        else
+        {
+            CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+                ((unsigned int)(ExtSeq+1)<<24) + SeqOffset;
+        }
+    }
+    else
+    {
+        VerifyInstructionWord = SAB_VERIFY_PADSPI;
+        if (ICVByteCount > 0)
+        {
+            VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+        }
+        if (AntiReplay > 0 &&
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) == 0 &&
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) == 0)
+        {
+            /* Skip verification of sequence number in sequence number append
+               mode. */
+            VerifyInstructionWord += SAB_VERIFY_BIT_SEQ;
+        }
+        if (ICVByteCount == 0 || AntiReplay == 0 ||
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+        {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+            if (SAState_p->fLarge)
+            {
+                CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+            }
+            else
+#endif
+            {
+                CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+            }
+        }
+        else if (ExtSeq != 0 ||
+                 (AntiReplay != 0 &&
+                  SAParams_p->OffsetSeqNum + 2 == SAParams_p->OffsetSeqMask))
+        {
+            if (AntiReplay > 12)
+                CtxInstructionWord = SAB_CTX_SEQNUM +
+                     + SeqOffset;
+            else
+                CtxInstructionWord = SAB_CTX_SEQNUM +
+                    ((unsigned int)(2+AntiReplay)<<24) + SeqOffset;
+        }
+        else
+        {
+            CtxInstructionWord = SAB_CTX_INSEQNUM +
+                ((unsigned int)(1+AntiReplay)<<24) + SeqOffset;
+        }
+    }
+
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+    /* Compute the maximum amount by which the packet can be enlarged,
+       so discount that from the output MTU to judge whether a packet can
+       be processed without fragmentation. */
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        MTUDiscount = ESP_HDR_LEN + 1 + PadBlockByteCount +
+            IVByteCount + ICVByteCount;
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+                MTUDiscount += IPV4_HDR_LEN;
+            else
+                MTUDiscount += IPV6_HDR_LEN;
+
+            // for IPv4 tunnel, pre-calculate checksum on IP addresses and store them in the transform record
+            // this checksum does not include the final inversion and is performed on data
+            // as they stored in the memory
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+            {
+                // protection against NULL pointers
+                if ((SAParamsIPsec_p->SrcIPAddr_p != NULL)&&
+                    (SAParamsIPsec_p->DestIPAddr_p != NULL))
+                {
+                    // add the addresses (in order they are stored in the memory)
+                    CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, 0);
+                    CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, 2);
+                    CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, 0);
+                    CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, 2);
+
+                    // process the carries
+                    while ((CheckSum>>16) != 0)
+                        CheckSum = (CheckSum>>16) + (CheckSum & 0xffff);
+                }
+            }
+        }
+    }
+    /* Compute the checksum delta for internal NAT operations and for inbound
+       transport NAT-T checksum fixup */
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0 &&
+        (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0)
+    {
+        uint8_t IPLen = SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4?4:16;
+        unsigned int i;
+        // Compute source address delta only if both original and new source
+        // addresses are provided, otherwise assume source address is unchanged.
+        if (SAParamsIPsec_p->SrcIPAddr_p != NULL &&
+            SAParamsIPsec_p->OrigSrcIPAddr_p != NULL)
+        {
+            for (i=0; i<IPLen; i+=2)
+            {
+                CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, i);
+                CheckSum += get16no(SAParamsIPsec_p->OrigSrcIPAddr_p, i) ^ 0xffff;
+            }
+        }
+        // Compute destination address delta only if both original and
+        // new destination addresses are provided, otherwise assume
+        // destination address is unchanged.
+        if (SAParamsIPsec_p->DestIPAddr_p != NULL &&
+            SAParamsIPsec_p->OrigDestIPAddr_p != NULL)
+        {
+            for (i=0; i<IPLen; i+=2)
+            {
+                CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, i);
+                CheckSum += get16no(SAParamsIPsec_p->OrigDestIPAddr_p, i) ^ 0xffff;
+            }
+        }
+        // process the carries
+        while ((CheckSum>>16) != 0)
+            CheckSum = (CheckSum>>16) + (CheckSum & 0xffff);
+    }
+
+#endif
+
+    /* If NAT-T selected, select other header protocol range */
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+        HeaderProto += (SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT -
+                        SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS);
+
+    /* Write all parameters to their respective offsets */
+    if (SABuffer_p != NULL)
+    {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+        if (SAState_p->fLarge)
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+                       LargeTransformOffset] = flags;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAParamsIPsec_p->ContextRef;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+                       LargeTransformOffset] = TokenHeaderWord;
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0 &&
+                (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0)
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+                    LargeTransformOffset] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  CheckSum & 0xff,
+                                  CheckSum >> 8);
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+                           LargeTransformOffset] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  SAParamsIPsec_p->TTL,
+                                  SAParamsIPsec_p->DSCP);
+            else
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET
+                           + LargeTransformOffset] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  0,
+                                  0);
+
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+                       LargeTransformOffset] = CCMSalt;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+                       LargeTransformOffset] =
+                VerifyInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+                       LargeTransformOffset] =
+                CtxInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+                       LargeTransformOffset] = 0;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+            SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET +
+                       LargeTransformOffset] =
+                SAB_PACKBYTES(SAParamsIPsec_p->NATTSrcPort >> 8,
+                              SAParamsIPsec_p->NATTSrcPort & 0xff,
+                              SAParamsIPsec_p->NATTDestPort >> 8,
+                              SAParamsIPsec_p->NATTDestPort & 0xff);
+
+            if (HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL ||
+                HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL ||
+                HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL_NATT ||
+                HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL_NATT ||
+                (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+            {
+#ifdef SAB_STRICT_ARGS_CHECK
+                if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+                    SAParamsIPsec_p->DestIPAddr_p == NULL)
+                {
+                    LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+                    return SAB_INVALID_PARAMETER;
+                }
+#endif
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET + LargeTransformOffset,
+                                        SAParamsIPsec_p->SrcIPAddr_p,
+                                        (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET + LargeTransformOffset,
+                                        SAParamsIPsec_p->DestIPAddr_p,
+                                        (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET
+                // checksum (only for IPv4)
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+                    SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET +
+                        LargeTransformOffset] = CheckSum;
+#endif
+            }
+
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET +
+                       LargeTransformOffset] =  MTUDiscount;
+#endif /* SAB_ENABLE_EXTENDED_TUNNEL_HEADER */
+        }
+        else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+        {
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+                SAParamsIPsec_p->ContextRef;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+                SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0 &&
+                (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0)
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  CheckSum & 0xff,
+                                  CheckSum >> 8);
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  SAParamsIPsec_p->TTL,
+                                  SAParamsIPsec_p->DSCP);
+            else
+                SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+                    SAB_PACKBYTES(PadBlockByteCount/2,
+                                  0,
+                                  0,
+                                  0);
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = CCMSalt;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+                VerifyInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+                CtxInstructionWord;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+            SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET] =
+                SAB_PACKBYTES(SAParamsIPsec_p->NATTSrcPort >> 8,
+                              SAParamsIPsec_p->NATTSrcPort & 0xff,
+                              SAParamsIPsec_p->NATTDestPort >> 8,
+                              SAParamsIPsec_p->NATTDestPort & 0xff);
+
+            if (HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL ||
+                HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL ||
+                HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL_NATT ||
+                HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL_NATT ||
+                (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+            {
+#ifdef SAB_STRICT_ARGS_CHECK
+                if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+                    SAParamsIPsec_p->DestIPAddr_p == NULL)
+                {
+                    LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+                    return SAB_INVALID_PARAMETER;
+                }
+#endif
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET,
+                                        SAParamsIPsec_p->SrcIPAddr_p,
+                                        (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET,
+                                        SAParamsIPsec_p->DestIPAddr_p,
+                                        (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET
+                // checksum (only for IPv4)
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+                    SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET] = CheckSum;
+#endif
+
+            }
+            SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET] =  MTUDiscount;
+#endif /* SAB_ENABLE_EXTENDED_TUNNEL_HEADER */
+        }
+    }
+    return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_IPSEC_EXTENDED */
+
+
+/* end of file sa_builder_extended_ipsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c
new file mode 100644
index 0000000..38b3312
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c
@@ -0,0 +1,187 @@
+/* sa_builder_extended_macsec.c
+ *
+ * MACsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the MACsec specific part of an SA) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetMACsecParams */
+#include "sa_builder_macsec.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#define SAB_MACSEC_ETHER_TYPE 0x88e5
+/* Various bits in the TCI byte */
+#define SAB_MACSEC_TCI_ES  BIT_6
+#define SAB_MACSEC_TCI_SC  BIT_5
+#define SAB_MACSEC_TCI_SCB BIT_4
+#define SAB_MACSEC_TCI_E   BIT_3
+#define SAB_MACSEC_TCI_C   BIT_2
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedMACsecParams(SABuilder_Params_t *const SAParams_p,
+                         SABuilder_State_t * const SAState_p,
+                         uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_MACsec_t *SAParamsMACsec_p =
+        (SABuilder_Params_MACsec_t *)(SAParams_p->ProtocolExtension_p);
+    uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+    SABuilder_ESPProtocol_t ESPProto;
+    SABuilder_HeaderProtocol_t HeaderProto;
+    uint8_t IVByteCount;
+    uint8_t ICVByteCount;
+    uint8_t SeqOffset;
+    uint8_t TCI; /* TCI byte in SECtag */
+    uint32_t flags = 0;
+    uint32_t VerifyInstructionWord, CtxInstructionWord;
+
+    IDENTIFIER_NOT_USED(SAState_p);
+
+    if (SAParamsMACsec_p == NULL)
+    {
+        LOG_CRIT("SABuilder: MACsec extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    SeqOffset = SAParams_p->OffsetSeqNum;
+    ICVByteCount = 16;
+    TCI = SAParamsMACsec_p->AN;
+    if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_ES) != 0)
+    {
+        TCI |= SAB_MACSEC_TCI_ES;
+    }
+    if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SC) != 0)
+    {
+        IVByteCount = 8;
+        TCI |= SAB_MACSEC_TCI_SC;
+    }
+    else
+    {
+        IVByteCount = 0;
+    }
+    if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SCB) != 0)
+    {
+        TCI |= SAB_MACSEC_TCI_SCB;
+    }
+
+    if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+        TCI |= SAB_MACSEC_TCI_E | SAB_MACSEC_TCI_C;
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        HeaderProto = SAB_HDR_MACSEC_OUT;
+        if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+            ESPProto = SAB_MACSEC_PROTO_OUT_GCM;
+        else
+            ESPProto = SAB_MACSEC_PROTO_OUT_GMAC;
+        VerifyInstructionWord = SAB_VERIFY_NONE;
+        CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+            ((unsigned int)(1<<24)) + SeqOffset;
+    }
+    else
+    {
+        HeaderProto = SAB_HDR_MACSEC_IN;
+        if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+            ESPProto = SAB_MACSEC_PROTO_IN_GCM;
+        else
+            ESPProto = SAB_MACSEC_PROTO_IN_GMAC;
+        VerifyInstructionWord = SAB_VERIFY_NONE + SAB_VERIFY_BIT_H +
+            SAB_VERIFY_BIT_SEQ + ICVByteCount;
+        CtxInstructionWord = SAB_CTX_SEQNUM +
+            ((unsigned int)(1<<24)) + SeqOffset;
+    }
+
+    /* Write all parameters to their respective offsets */
+    if (SABuffer_p != NULL)
+    {
+        /* Do not support large transform records as Macsec will never
+           use HMAC-SHA512 */
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+            SAParamsMACsec_p->ContextRef;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+            SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+            SAB_PACKBYTES(SAB_MACSEC_ETHER_TYPE>>8,
+                          SAB_MACSEC_ETHER_TYPE &0xff, TCI, 0);
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] =
+            SAParamsMACsec_p->ConfOffset;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+                VerifyInstructionWord;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+            CtxInstructionWord;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+        SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+
+        SABuilderLib_CopyKeyMat(SABuffer_p,
+                                FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET,
+                                SAParamsMACsec_p->SCI_p, 8);
+    }
+    return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_MACSEC_EXTENDED */
+
+
+/* end of file sa_builder_extended_dtls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c
new file mode 100644
index 0000000..eb5144d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c
@@ -0,0 +1,722 @@
+/* sa_builder_ipsec.c
+ *
+ * IPsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the IPSec specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_ipsec.h"
+#include "sa_builder_internal.h" /* SABuilder_SetIpsecParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_IPSEC
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#ifdef SAB_ENABLE_1024BIT_SEQMASK
+#define SAB_SEQUENCE_MAXBITS 1024
+#elif defined(SAB_ENABLE_384BIT_SEQMASK)
+#define SAB_SEQUENCE_MAXBITS 384
+#else
+#define SAB_SEQUENCE_MAXBITS 128
+#endif
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_ESP
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_IPsec_t extension with sensible defaults for ESP
+ * processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsIPsec_p (output)
+ *   Pointer to IPsec parameter extension to be filled in
+ * spi (input)
+ *   SPI of the newly created parameter structure (must not be zero).
+ * TunnelTransport (input)
+ *   Must be one of SAB_IPSEC_TUNNEL or SAB_IPSEC_TRANSPORT.
+ * IPMode (input)
+ *   Must be one of SAB_IPSEC_IPV4 or SAB_IPSEC_IPV6.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL, which is illegal according to the IPsec standards, but it is
+ * possible to use this setting for debug purposes.
+ *
+ * Both the SAParams_p and SAParamsIPsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsIPsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_ESP(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_IPsec_t * const SAParamsIPsec_p,
+    const uint32_t spi,
+    const uint32_t TunnelTransport,
+    const uint32_t IPMode,
+    const SABuilder_Direction_t direction)
+{
+    int i;
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SAParamsIPsec_p == NULL)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (spi == 0)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: SPI may not be 0.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (TunnelTransport != SAB_IPSEC_TUNNEL &&
+        TunnelTransport != SAB_IPSEC_TRANSPORT)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid TunnelTransport.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (IPMode != SAB_IPSEC_IPV4 && IPMode != SAB_IPSEC_IPV6)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid IPMode.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (direction != SAB_DIRECTION_OUTBOUND &&
+        direction != SAB_DIRECTION_INBOUND)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAParams_p->protocol = SAB_PROTO_IPSEC;
+    SAParams_p->direction = direction;
+    SAParams_p->ProtocolExtension_p = (void*)SAParamsIPsec_p;
+    SAParams_p->flags = 0;
+    SAParams_p->RedirectInterface = 0;
+
+    SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+    SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+    SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+    SAParams_p->CryptoParameter = 0;
+    SAParams_p->KeyByteCount = 0;
+    SAParams_p->Key_p = NULL;
+    SAParams_p->IV_p = NULL;
+    SAParams_p->Nonce_p = NULL;
+
+    SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+    SAParams_p->AuthKey1_p = NULL;
+    SAParams_p->AuthKey2_p = NULL;
+    SAParams_p->AuthKey3_p = NULL;
+    SAParams_p->AuthKeyByteCount = 0;
+
+    SAParams_p->OffsetARC4StateRecord = 0;
+    SAParams_p->CW0 = 0;
+    SAParams_p->CW1 = 0;
+    SAParams_p->OffsetDigest0 = 0;
+    SAParams_p->OffsetDigest1 = 0;
+    SAParams_p->OffsetSeqNum = 0;
+    SAParams_p->OffsetSeqMask = 0;
+    SAParams_p->OffsetIV = 0;
+    SAParams_p->OffsetIJPtr = 0;
+    SAParams_p->OffsetARC4State = 0;
+    SAParams_p->SeqNumWord32Count = 0;
+    SAParams_p->SeqMaskWord32Count = 0;
+    SAParams_p->IVWord32Count = 0;
+
+    SAParamsIPsec_p->spi = spi;
+    SAParamsIPsec_p->IPsecFlags = SAB_IPSEC_ESP | TunnelTransport | IPMode;
+    SAParamsIPsec_p->SeqNum = 0;
+    SAParamsIPsec_p->SeqNumHi = 0;
+    SAParamsIPsec_p->SeqMask[0] = 1;
+    for (i=1; i<SA_SEQ_MASK_WORD_COUNT; i++)
+        SAParamsIPsec_p->SeqMask[i] = 0;
+    SAParamsIPsec_p->PadAlignment = 0;
+    SAParamsIPsec_p->ICVByteCount = 0;
+    SAParamsIPsec_p->SrcIPAddr_p = NULL;
+    SAParamsIPsec_p->DestIPAddr_p = NULL;
+    SAParamsIPsec_p->OrigSrcIPAddr_p = NULL;
+    SAParamsIPsec_p->OrigDestIPAddr_p = NULL;
+    SAParamsIPsec_p->NATTSrcPort = 4500;
+    SAParamsIPsec_p->NATTDestPort = 4500;
+    SAParamsIPsec_p->ContextRef = 0;
+    SAParamsIPsec_p->TTL = 240;
+    SAParamsIPsec_p->DSCP = 0;
+    SAParamsIPsec_p->SequenceMaskBitCount = 0;
+    return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.
+ *
+ * SAParams_p (input, updated)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetIPsecParams(SABuilder_Params_t *const SAParams_p,
+                         SABuilder_State_t * const SAState_p,
+                         uint32_t * const SABuffer_p)
+{
+    unsigned int IVOffset = 0;
+    SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+    bool fFixedSeqOffset = false;
+    SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsIPsec_p == NULL)
+    {
+        LOG_CRIT("SABuilder: IPsec extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* First check whether AH or ESP flags are correct */
+
+    if ( (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_AH) != 0)
+    {
+#ifdef SAB_ENABLE_IPSEC_AH
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL ||
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+        {
+            LOG_CRIT("SABuilder: AH does not support crypto.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+#else
+        LOG_CRIT("SABuilder: AH unsupported..\n");
+        return SAB_INVALID_PARAMETER;
+#endif
+    }
+
+#ifndef SAB_ENABLE_IPSEC_ESP
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+    {
+        LOG_CRIT("SABuilder: ESP unsupported.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    /* Check for supported algorithms and crypto modes in IPsec */
+    if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_DES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0) ||
+        (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL && (
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CTR &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GMAC &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CHACHA_CTR32)))
+    {
+        LOG_CRIT("SABuilder: IPsec: crypto algorithm/mode not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Check for supported authentication algorithms in IPsec */
+    if (SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_MD5 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_256 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_384 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_512 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_XCBC_MAC &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_CMAC_128 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM &&
+        SAParams_p->AuthAlgo != SAB_AUTH_POLY1305 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SM3)
+    {
+        LOG_CRIT("SABuilder: IPsec: auth algorithm not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Add SPI to SA record */
+    if (SABuffer_p != NULL)
+        SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->spi;
+    SAState_p->CurrentOffset += 1;
+
+    /* Determine whether we will have a fixed sequence number offset */
+    if (SAParams_p->direction == SAB_DIRECTION_INBOUND)
+    {
+        /* Determine size of sequence number mask in bits */
+        if (SAParamsIPsec_p->SequenceMaskBitCount == 0)
+        {
+            /* Some flags indicate specific mask sizes */
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_384) != 0)
+            {
+                SAParamsIPsec_p->SequenceMaskBitCount = 384;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_256) != 0)
+            {
+                SAParamsIPsec_p->SequenceMaskBitCount = 256;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_128) != 0)
+            {
+                SAParamsIPsec_p->SequenceMaskBitCount = 128;
+            }
+            else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_32) != 0)
+            {
+                SAParamsIPsec_p->SequenceMaskBitCount = 32;
+            }
+            else
+            {
+                SAParamsIPsec_p->SequenceMaskBitCount = 64;
+            }
+        }
+        if (SAParamsIPsec_p->SequenceMaskBitCount > SAB_SEQUENCE_MAXBITS ||
+            (SAParamsIPsec_p->SequenceMaskBitCount & 0x1f) != 0)
+        {
+            LOG_CRIT("SABuilder: Illegal sequence mask size.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+#ifdef SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+        fFixedSeqOffset = true;
+#else
+        if (SAParamsIPsec_p->SequenceMaskBitCount > 128 ||
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_FIXED_SEQ_OFFSET) != 0)
+        {
+            fFixedSeqOffset = true;
+        }
+#endif
+        if (SAParamsIPsec_p->SequenceMaskBitCount ==32)
+        {
+            fFixedSeqOffset = false; /* not supported for 32-bit mask */
+        }
+    }
+
+    if (fFixedSeqOffset)
+    {
+        /* Use a fixed sequence number offset for inbound if the hardware
+           supports it. */
+        /* Take care to insert the IV (nonce) just after the SPI. */
+        IVOffset = SAState_p->CurrentOffset;
+
+        /* Select one of two fixed offsets for the sequence number */
+        if (SAState_p->CurrentOffset < SAB_SEQNUM_LO_FIX_OFFSET)
+        {
+            SAState_p->CurrentOffset = SAB_SEQNUM_LO_FIX_OFFSET;
+        }
+        else
+        {
+            SAState_p->CurrentOffset = SAB_SEQNUM_HI_FIX_OFFSET;
+        }
+
+        /* Add sequence number */
+        SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+
+        if (SABuffer_p != NULL)
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNum;
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+        {
+            if (SABuffer_p != NULL)
+                SABuffer_p[SAState_p->CurrentOffset+1] = SAParamsIPsec_p->SeqNumHi;
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64_FIX;
+            SAParams_p->SeqNumWord32Count = 2;
+        }
+        else
+        {
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_32_FIX;
+            SAParams_p->SeqNumWord32Count = 1;
+        }
+        // Always reserve 2 words for the sequence number.
+        SAState_p->CurrentOffset += 2;
+    }
+    else
+    {
+        /* Add sequence number */
+        SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+
+        if (SABuffer_p != NULL)
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNum;
+        SAState_p->CurrentOffset += 1;
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+        {
+            if (SABuffer_p != NULL)
+                SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNumHi;
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64;
+            SAState_p->CurrentOffset += 1;
+
+            SAParams_p->SeqNumWord32Count = 2;
+        }
+        else
+        {
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_32;
+            SAParams_p->SeqNumWord32Count = 1;
+        }
+    }
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL &&
+            SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_NULL_OUT;
+        else if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+        else if (SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT;
+        else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM ||
+                 SAParams_p->AuthAlgo==SAB_AUTH_AES_GMAC)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+
+        /* Some versions of the hardware can update the sequence number
+           early, so multiple engines can operate in parallel. */
+        SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+        SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+
+        SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY)!=0 &&
+            (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) == 0)
+        {
+            /* Disable outbound sequence number rollover checking by putting
+               an 64-sequence number in the SA. This will not be
+               used in authentication (no ESN) */
+            if (SABuffer_p != NULL)
+                SABuffer_p[SAState_p->CurrentOffset] = 0;
+            SAState_p->CW0 |= SAB_CW0_SEQNUM_64;
+            SAState_p->CurrentOffset += 1;
+        }
+
+        /* Take care of IV and nonce */
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+        {
+            if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+                SAParams_p->IVSrc = SAB_IV_SRC_SEQ;
+
+            /* Add nonce, always present */
+            SAState_p->CW1 |= SAB_CW1_IV0;
+            if (SABuffer_p != NULL)
+            {
+                if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+                    SABuffer_p[SAState_p->CurrentOffset] =
+                        (SAParams_p->Nonce_p[0] << 8)  |
+                        (SAParams_p->Nonce_p[1] << 16) |
+                        (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+                else
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->Nonce_p,
+                                            sizeof(uint32_t));
+            }
+            SAState_p->CurrentOffset +=1;
+
+            if (SAParams_p->IVSrc == SAB_IV_SRC_SEQ)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_INCR_SEQ;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+                SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        SAState_p->CurrentOffset,
+                                        SAParams_p->IV_p,
+                                        2*sizeof(uint32_t));
+                SAState_p->CurrentOffset +=2;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+                if (SAParams_p->IV_p == NULL)
+                {
+                    LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                    return SAB_INVALID_PARAMETER;
+                }
+#endif
+                SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                SAParams_p->IVWord32Count = 2;
+
+                SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                        SAParams_p->IV_p, 8);
+                SAState_p->CurrentOffset += 2;
+            }
+            else
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR;
+            }
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+            {
+                /* Add 0 counter field (IV3) */
+                SAState_p->CW1 |= SAB_CW1_IV3;
+                if(SABuffer_p != NULL)
+                    SABuffer_p[SAState_p->CurrentOffset] = 0;
+                SAState_p->CurrentOffset+=1;
+            }
+        }
+        else if (SAState_p->IVWords > 0)
+        { /* CBC mode, non-null */
+            if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+                SAParams_p->IVSrc = SAB_IV_SRC_PRNG;
+            SAState_p->CW1 |= SAB_CW1_IV_FULL;
+            if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+                    if(SAState_p->IVWords == 4)
+                        SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+                    if (SAParams_p->IV_p == NULL)
+                    {
+                        LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                        return SAB_INVALID_PARAMETER;
+                    }
+#endif
+                    SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                    SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                       SAState_p->CurrentOffset,
+                                       SAParams_p->IV_p,
+                                       SAState_p->IVWords * sizeof(uint32_t));
+                    SAState_p->CurrentOffset += SAState_p->IVWords;
+            }
+        }
+    }
+    else
+    {   /* Inbound */
+        unsigned int InputMaskWordCount =
+            SAParamsIPsec_p->SequenceMaskBitCount / 32;
+        unsigned int AllocMaskWordCount;
+
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL &&
+            SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_NULL_IN;
+        else if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+        else if (SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT;
+        else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM)
+            SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+        SAState_p->CW1 |= SAB_CW1_PAD_IPSEC;
+
+        /* Add sequence mask  Always add one even with no anti-replay*/
+        SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) != 0)
+            SAState_p->CW0 |= SAB_CW0_SEQNUM_APPEND;
+
+        /* Determine the required hardware mask size in words and set
+           control words accordingly. */
+        if (InputMaskWordCount  == 1)
+        {
+            AllocMaskWordCount = 1;
+            SAState_p->CW0 |= SAB_CW0_MASK_32;
+        }
+        else if (InputMaskWordCount  == 2)
+        {
+            AllocMaskWordCount = 2;
+            if (fFixedSeqOffset)
+            {
+                SAState_p->CW0 |= SAB_CW0_MASK_64_FIX;
+            }
+            else
+            {
+                SAState_p->CW0 |= SAB_CW0_MASK_64;
+            }
+        }
+        else if (InputMaskWordCount <= 4)
+        {
+            AllocMaskWordCount = 4;
+            if (fFixedSeqOffset)
+            {
+                SAState_p->CW0 |= SAB_CW0_MASK_128_FIX;
+            }
+            else
+            {
+                SAState_p->CW0 |= SAB_CW0_MASK_128;
+            }
+        }
+#ifdef SAB_ENABLE_256BIT_SEQMASK
+        else if (InputMaskWordCount <= 8)
+        {
+            AllocMaskWordCount = 8;
+            SAState_p->CW0 |= SAB_CW0_MASK_256_FIX;
+        }
+#endif
+        else if (InputMaskWordCount <= 12)
+        {
+            AllocMaskWordCount = 12;
+            SAState_p->CW0 |= SAB_CW0_MASK_384_FIX;
+        }
+        else
+        {
+            AllocMaskWordCount = 32;
+            SAState_p->CW0 |= SAB_CW0_MASK_1024_FIX;
+            SAState_p->fLargeMask = true;
+            SAState_p->fLarge = true;
+        }
+        if(SABuffer_p != NULL)
+        {
+            unsigned int i;
+            if (AllocMaskWordCount <= SA_SEQ_MASK_WORD_COUNT)
+            {
+                for (i = 0; i < InputMaskWordCount; i++)
+                    SABuffer_p[SAState_p->CurrentOffset+i] =
+                        SAParamsIPsec_p->SeqMask[i];
+                /* If the input mask is smaller than the one picked by the
+                   hardware, fill the remaining words with all-one, the
+                   hardware will treat these words as invalid.
+                */
+                for (i= InputMaskWordCount; i < AllocMaskWordCount; i++)
+                    SABuffer_p[SAState_p->CurrentOffset+i] = 0xffffffff;
+            }
+            else
+            {
+                /* Mask too big to store in parameter structure.
+                   Also need to shift the '1' bit to correct position */
+                uint32_t WordIdx, BitMask;
+                for (i= 0; i < AllocMaskWordCount; i++)
+                    SABuffer_p[SAState_p->CurrentOffset+i] = 0;
+                WordIdx = (SAParamsIPsec_p->SeqNum & MASK_10_BITS) >> 5;
+                BitMask = 1 << (SAParamsIPsec_p->SeqNum & MASK_5_BITS);
+                SABuffer_p[SAState_p->CurrentOffset+WordIdx] = BitMask;
+            }
+        }
+        SAState_p->CurrentOffset += AllocMaskWordCount;
+        SAParams_p->SeqMaskWord32Count = InputMaskWordCount;
+
+        /* Add nonce for CTR and related modes */
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM||
+            SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+        {
+            if (IVOffset == 0)
+                IVOffset = SAState_p->CurrentOffset;
+
+            SAState_p->CW1 |= SAB_CW1_IV0;
+
+            /* For Poly/Chacha, we need to run in XOR IV mode with
+              delayed OTK in order to make the OTK derivation from the
+              extracted IV work */
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+            {
+                SAState_p->CW1 |= SAB_CW1_CRYPTO_NONCE_XOR|
+                    SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK;
+                /* need all 3 IV double words - for IV=seqno these need to be
+                   zeroized */
+                SAState_p->CW1 |= SAB_CW1_IV1|SAB_CW1_IV2;
+                if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+                    SAState_p->CW1 |= SAB_CW1_IV_CTR;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+                SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+
+            if (SABuffer_p != NULL)
+            {
+                if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+                {
+                    SABuffer_p[IVOffset] =
+                        (SAParams_p->Nonce_p[0] << 8)  |
+                        (SAParams_p->Nonce_p[1] << 16) |
+                        (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+                }
+                else
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            IVOffset,
+                                            SAParams_p->Nonce_p,
+                                            sizeof(uint32_t));
+            }
+            IVOffset += 1;
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+            {
+                /* Add 0 counter field (IV3) */
+                SAState_p->CW1 |= SAB_CW1_IV3;
+                if(SABuffer_p != NULL)
+                    SABuffer_p[IVOffset] = 0;
+                IVOffset += 1;
+            }
+            else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+            {
+                /* For ChaCha20 the IV1 and IV2 words are required to be 0 */
+                SABuilderLib_ZeroFill(SABuffer_p, IVOffset, 2*sizeof(uint32_t));
+                IVOffset +=2;
+            }
+            if (IVOffset > SAState_p->CurrentOffset)
+            {
+                SAState_p->CurrentOffset = IVOffset;
+            }
+         }
+    }
+    return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_IPSEC */
+
+/* end of file sa_builder_ipsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c
new file mode 100644
index 0000000..e6a7f99
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c
@@ -0,0 +1,275 @@
+/* sa_builder_macsec.c
+ *
+ * MACsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the MACsec specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_macsec.h"
+#include "sa_builder_internal.h" /* SABuilder_SetMACsecParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_MACSEC
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_MACsec
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_MACsec_t extension with sensible defaults for MACsec
+ * processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsMACsec_p (output)
+ *   Pointer to MACsec parameter extension to be filled in
+ * SCI_p (input)
+ *   Pointer to Secure Channel Identifier, 8 bytes.
+ * AN (input)
+ *   Association number, a number for 0 to 3.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsMACsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsMACsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_MACsec(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_MACsec_t * const SAParamsMACsec_p,
+    const uint8_t *SCI_p,
+    const uint8_t AN,
+    const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SAParamsMACsec_p == NULL || SCI_p == NULL)
+    {
+        LOG_CRIT("SABuilder_Init_MACsec: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (AN > 3)
+    {
+        LOG_CRIT("SABuilder_Init_MACsec: Invalid Association Number.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (direction != SAB_DIRECTION_OUTBOUND &&
+        direction != SAB_DIRECTION_INBOUND)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAParams_p->protocol = SAB_PROTO_MACSEC;
+    SAParams_p->direction = direction;
+    SAParams_p->ProtocolExtension_p = (void*)SAParamsMACsec_p;
+    SAParams_p->flags = 0;
+    SAParams_p->RedirectInterface = 0;
+
+    SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+    SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+    SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+    SAParams_p->CryptoParameter = 0;
+    SAParams_p->KeyByteCount = 0;
+    SAParams_p->Key_p = NULL;
+    SAParams_p->IV_p = NULL;
+    SAParams_p->Nonce_p = NULL;
+
+    SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+    SAParams_p->AuthKey1_p = NULL;
+    SAParams_p->AuthKey2_p = NULL;
+    SAParams_p->AuthKey3_p = NULL;
+    SAParams_p->AuthKeyByteCount = 0;
+
+    SAParams_p->OffsetARC4StateRecord = 0;
+    SAParams_p->CW0 = 0;
+    SAParams_p->CW1 = 0;
+    SAParams_p->OffsetDigest0 = 0;
+    SAParams_p->OffsetDigest1 = 0;
+    SAParams_p->OffsetSeqNum = 0;
+    SAParams_p->OffsetSeqMask = 0;
+    SAParams_p->OffsetIV = 0;
+    SAParams_p->OffsetIJPtr = 0;
+    SAParams_p->OffsetARC4State = 0;
+    SAParams_p->SeqNumWord32Count = 0;
+    SAParams_p->SeqMaskWord32Count = 0;
+    SAParams_p->IVWord32Count = 0;
+
+    SAParamsMACsec_p->MACsecFlags = 0;
+    SAParamsMACsec_p->SCI_p = SCI_p;
+    SAParamsMACsec_p->AN = AN;
+    SAParamsMACsec_p->SeqNum = 0;
+    SAParamsMACsec_p->ReplayWindow = 0;
+    SAParamsMACsec_p->ConfOffset = 0;
+    SAParamsMACsec_p->ContextRef = 0;
+
+    return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetMACsecParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_MACsec_t *SAParamsMACsec_p;
+    SAParamsMACsec_p = (SABuilder_Params_MACsec_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsMACsec_p == NULL)
+    {
+        LOG_CRIT("SABuilder: MACsec extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Allow only AES-GMAC and AES-GCM */
+    if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
+    {
+        LOG_CRIT("SABuilder: Only AES-GCM and GMAC allowed wtih MACsec\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if ( (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_ES) != 0 &&
+         (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SC) != 0)
+    {
+        LOG_CRIT("SABuilder: MACSEC if ES is set, then SC must be zero,\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Add sequence number */
+    SAState_p->CW0 |= SAB_CW0_SEQNUM_32;
+    SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+    SAParams_p->SeqNumWord32Count = 1;
+    SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+
+    if (SABuffer_p != NULL)
+        SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
+    SAState_p->CurrentOffset += 1;
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+            SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+        /* Some versions of the hardware can update the sequence number
+           early, so multiple engines can operate in parallel. */
+        SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+        SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+    }
+    else
+    {
+        SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+        /* Add 'sequence number mask' parameter, which is the replay
+           window size */
+        SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+        if(SABuffer_p != NULL)
+        {
+            SABuffer_p[SAState_p->CurrentOffset] =
+                SAParamsMACsec_p->ReplayWindow;
+            SABuffer_p[SAState_p->CurrentOffset+1] = 0; // Add dummy mask word.
+        }
+        SAParams_p->SeqMaskWord32Count = 1;
+        SAState_p->CurrentOffset += 2;
+        SAState_p->CW0 |= SAB_CW0_MASK_32;
+        SAState_p->CW1 |= SAB_CW1_MACSEC_SEQCHECK|SAB_CW1_NO_MASK_UPDATE;
+    }
+
+    /* Add SCI (IV0 and IV1) */
+    SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV0 | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParamsMACsec_p->SCI_p == NULL)
+    {
+        LOG_CRIT("SABuilder: NULL pointer SCI.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+    SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+    SAParams_p->IVWord32Count = 2;
+
+    SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                            SAParamsMACsec_p->SCI_p, 8);
+    SAState_p->CurrentOffset += 2;
+
+    /* Add sequence number once more (IV2) */
+    if (SABuffer_p != NULL)
+        SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
+    SAState_p->CurrentOffset += 1;
+
+    return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_MACSEC */
+
+/* end of file sa_builder_macsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c
new file mode 100644
index 0000000..a43e711
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c
@@ -0,0 +1,228 @@
+/* sa_builder_srtp.c
+ *
+ * SRTP specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the SRTP
+ * specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_srtp.h"
+#include "sa_builder_internal.h" /* SABuilder_SetSSLTLSParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_SRTP
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SRTP
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_SRTP_t extension with sensible defaults for
+ * SRTP processing..
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsSRTP_p (output)
+ *   Pointer to SRTP parameter extension to be filled in
+ * IsSRTCP (input)
+ *   true if the SA is for SRTCP.
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Tis function initializes the authentication algorithm to HMAC_SHA1.
+ * The application has to fill in the appropriate keys. The crypto algorithm
+ * is initialized to NULL. It can be changed to AES ICM and then a crypto
+ * key has to be added as well.
+ *
+ * Both the SAParams_p and SAParamsSRTP_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSRTP_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SRTP(
+        SABuilder_Params_t * const SAParams_p,
+        SABuilder_Params_SRTP_t * const SAParamsSRTP_p,
+        const bool IsSRTCP,
+        const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SAParamsSRTP_p == NULL)
+    {
+        LOG_CRIT("SABuilder_Init_SSLTLS: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (direction != SAB_DIRECTION_OUTBOUND &&
+        direction != SAB_DIRECTION_INBOUND)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAParams_p->protocol = SAB_PROTO_SRTP;
+    SAParams_p->direction = direction;
+    SAParams_p->ProtocolExtension_p = (void*)SAParamsSRTP_p;
+    SAParams_p->flags = 0;
+    SAParams_p->RedirectInterface = 0;
+
+    SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+    SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+    SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+    SAParams_p->CryptoParameter = 0;
+    SAParams_p->KeyByteCount = 0;
+    SAParams_p->Key_p = NULL;
+    SAParams_p->IV_p = NULL;
+    SAParams_p->Nonce_p = NULL;
+
+    SAParams_p->AuthAlgo = SAB_AUTH_HMAC_SHA1;
+    SAParams_p->AuthKey1_p = NULL;
+    SAParams_p->AuthKey2_p = NULL;
+    SAParams_p->AuthKey3_p = NULL;
+    SAParams_p->AuthKeyByteCount = 0;
+
+    SAParams_p->OffsetARC4StateRecord = 0;
+    SAParams_p->CW0 = 0;
+    SAParams_p->CW1 = 0;
+    SAParams_p->OffsetDigest0 = 0;
+    SAParams_p->OffsetDigest1 = 0;
+    SAParams_p->OffsetSeqNum = 0;
+    SAParams_p->OffsetSeqMask = 0;
+    SAParams_p->OffsetIV = 0;
+    SAParams_p->OffsetIJPtr = 0;
+    SAParams_p->OffsetARC4State = 0;
+    SAParams_p->SeqNumWord32Count = 0;
+    SAParams_p->SeqMaskWord32Count = 0;
+    SAParams_p->IVWord32Count = 0;
+
+    SAParamsSRTP_p->SRTPFlags = 0;
+    if (IsSRTCP)
+        SAParamsSRTP_p->SRTPFlags |= SAB_SRTP_FLAG_SRTCP;
+    SAParamsSRTP_p->MKI = 0;
+    SAParamsSRTP_p->ICVByteCount = 10;
+
+    return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSRTPParams
+ *
+ * Fill in SRTP-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated.
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSRTPParams(SABuilder_Params_t *const SAParams_p,
+                        SABuilder_State_t * const SAState_p,
+                        uint32_t * const SABuffer_p)
+{
+    SABuilder_Params_SRTP_t *SAParamsSRTP_p;
+    SAParamsSRTP_p = (SABuilder_Params_SRTP_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsSRTP_p == NULL)
+    {
+        LOG_CRIT("SABuilder: SRTP extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_AES)
+    {
+        SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR or ICM);
+        SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD | SAB_CW1_IV_CTR;
+    }
+    else if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {
+        LOG_CRIT("SABuilder: I: crypto algorithm not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1)
+    {
+        LOG_CRIT("SABuilder: I: authentication algorithm not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Add MKI (as the SPI field) */
+    if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_INCLUDE_MKI) != 0)
+    {
+        SAState_p->CW0 |= SAB_CW0_SPI;
+        if (SABuffer_p != NULL)
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsSRTP_p->MKI;
+        SAState_p->CurrentOffset += 1;
+    }
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+    }
+    else
+    {
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+    }
+
+    return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_PROTO_SRTP */
+
+
+/* end of file sa_builder_srtp.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c
new file mode 100644
index 0000000..6a47ad0
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c
@@ -0,0 +1,760 @@
+/* sa_builder_ssltls.c
+ *
+ * SSL/TLS/DTLS specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the SSL/TLS/DTLS specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_ssltls.h"
+#include "sa_builder_internal.h" /* SABuilder_SetSSLTLSParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#ifdef SAB_ENABLE_384BIT_SEQMASK
+#define SAB_SEQUENCE_MAXBITS 384
+#else
+#define SAB_SEQUENCE_MAXBITS 128
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SSLTLS
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_SSLTLS_t extension with sensible defaults for SSL, TLS
+ * and DTLS processing.
+ *
+ * SAParams_p (output)
+ *   Pointer to SA parameter structure to be filled in.
+ * SAParamsSSLTLS_p (output)
+ *   Pointer to SSLTLS parameter extension to be filled in
+ * version (input)
+ *   Version code for the desired protcol (choose one of the SAB_*_VERSION_*
+ *   constants from sa_builder_params_ssltls.h).
+ * direction (input)
+ *   Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsSSLTLS_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSSSLTLS_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ *   or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SSLTLS(
+    SABuilder_Params_t * const SAParams_p,
+    SABuilder_Params_SSLTLS_t * const SAParamsSSLTLS_p,
+    const uint16_t version,
+    const SABuilder_Direction_t direction)
+{
+    int i;
+#ifdef SAB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || SAParamsSSLTLS_p == NULL)
+    {
+        LOG_CRIT("SABuilder_Init_SSLTLS: NULL pointer parameter supplied.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (version != SAB_SSL_VERSION_3_0 &&
+        version != SAB_TLS_VERSION_1_0 &&
+        version != SAB_TLS_VERSION_1_1 &&
+        version != SAB_TLS_VERSION_1_2 &&
+        version != SAB_TLS_VERSION_1_3 &&
+        version != SAB_DTLS_VERSION_1_0 &&
+        version != SAB_DTLS_VERSION_1_2)
+    {
+        LOG_CRIT("SABuilder_Init_SSLTLS: Invalid protocol version.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    if (direction != SAB_DIRECTION_OUTBOUND &&
+        direction != SAB_DIRECTION_INBOUND)
+    {
+        LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+        return SAB_INVALID_PARAMETER;
+    }
+#endif
+
+    SAParams_p->protocol = SAB_PROTO_SSLTLS;
+    SAParams_p->direction = direction;
+    SAParams_p->ProtocolExtension_p = (void*)SAParamsSSLTLS_p;
+    SAParams_p->flags = 0;
+    SAParams_p->RedirectInterface = 0;
+
+    SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+    SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+    SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+    SAParams_p->CryptoParameter = 0;
+    SAParams_p->KeyByteCount = 0;
+    SAParams_p->Key_p = NULL;
+    SAParams_p->IV_p = NULL;
+    SAParams_p->Nonce_p = NULL;
+
+    SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+    SAParams_p->AuthKey1_p = NULL;
+    SAParams_p->AuthKey2_p = NULL;
+    SAParams_p->AuthKey3_p = NULL;
+    SAParams_p->AuthKeyByteCount = 0;
+
+    SAParams_p->OffsetARC4StateRecord = 0;
+    SAParams_p->CW0 = 0;
+    SAParams_p->CW1 = 0;
+    SAParams_p->OffsetDigest0 = 0;
+    SAParams_p->OffsetDigest1 = 0;
+    SAParams_p->OffsetSeqNum = 0;
+    SAParams_p->OffsetSeqMask = 0;
+    SAParams_p->OffsetIV = 0;
+    SAParams_p->OffsetIJPtr = 0;
+    SAParams_p->OffsetARC4State = 0;
+    SAParams_p->SeqNumWord32Count = 0;
+    SAParams_p->SeqMaskWord32Count = 0;
+    SAParams_p->IVWord32Count = 0;
+
+    SAParamsSSLTLS_p->SSLTLSFlags = 0;
+    SAParamsSSLTLS_p->version = version;
+    SAParamsSSLTLS_p->epoch = 0;
+    SAParamsSSLTLS_p->SeqNum = 0;
+    SAParamsSSLTLS_p->SeqNumHi = 0;
+    for (i=0; i<12; i++)
+        SAParamsSSLTLS_p->SeqMask[i] = 0;
+    SAParamsSSLTLS_p->PadAlignment = 0;
+    SAParamsSSLTLS_p->ContextRef = 0;
+    SAParamsSSLTLS_p->SequenceMaskBitCount = 0;
+    SAParamsSSLTLS_p->ICVByteCount = 0;
+    return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSSLTLSParams
+ *
+ * Fill in SSL/TLS/DTLS-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ *   The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ *   Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ *   The buffer in which the SA is built. If NULL, no SA will be built, but
+ *   state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ *    the buffer arguments  is a null pointer while the corresponding buffer
+ *    would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ *    is not supported on the hardware for which this SA builder
+ *    is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSSLTLSParams(SABuilder_Params_t *const SAParams_p,
+                          SABuilder_State_t * const SAState_p,
+                          uint32_t * const SABuffer_p)
+{
+    unsigned int IVOffset = 0;
+    SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p;
+    bool fFixedSeqOffset = false;
+    SAParamsSSLTLS_p = (SABuilder_Params_SSLTLS_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsSSLTLS_p == NULL)
+    {
+        LOG_CRIT("SABuilder: SSLTLS extension pointer is null\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Prohibit ARC4 in DTLS and TLS1.3 */
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR &&
+        (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3||
+         SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0||
+         SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+    {
+        LOG_CRIT("SABuilder: ARC4 not allowed with DTLS/TLS1.3\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Prohibit CBC mode or NULL crypto in TLS1.3 */
+    if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 &&
+        (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC ||
+         SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL))
+    {
+        LOG_CRIT("SABuilder: CBC or nullcrypto  not allowed with TLS1.3\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* AES GCM/CCM/Chacha20 is only allowed with TLS1.2/TLS1.3/DTLS1.2 */
+    if ((SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20 ||
+         SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM||
+         SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM) &&
+        SAParamsSSLTLS_p->version != SAB_TLS_VERSION_1_2 &&
+        SAParamsSSLTLS_p->version != SAB_TLS_VERSION_1_3 &&
+        SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2)
+    {
+        LOG_CRIT("SABuilder: AES-GCM/CCM/ChaCha20 only allowed with TLS/DTLS 1.2 and 1.3\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Prohibit stateless ARC4*/
+    if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR &&
+        SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATEFUL)
+    {
+        LOG_CRIT("SABuilder: ARC4 must be stateful\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Check for supported algorithms and crypto modes in SSL/TLS */
+    if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_DES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+         SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0) ||
+        (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+         SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATEFUL &&
+         SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+         SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+         SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+         SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CHACHA_CTR32))
+    {
+        LOG_CRIT("SABuilder: SSLTLS crypto algorithm/mode not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Check for supported authentication algorithms in SSL/TLS */
+    if (SAParams_p->AuthAlgo != SAB_AUTH_HMAC_MD5 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_SSLMAC_MD5 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_SSLMAC_SHA1 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_256 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_384 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_512 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+        SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM &&
+        SAParams_p->AuthAlgo != SAB_AUTH_POLY1305 &&
+        SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SM3)
+    {
+        LOG_CRIT("SABuilder: SSLTLS: auth algorithm not supported\n");
+        return SAB_INVALID_PARAMETER;
+    }
+
+    /* Add version to SA record */
+    if (SABuffer_p != NULL)
+    {
+        if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+        {
+            SABuffer_p[SAState_p->CurrentOffset] = SAB_TLS_VERSION_1_2<<16;
+            /* fixed type & version to be put in record for TLS1.3 */
+        }
+        else
+        {
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->version<<16;
+        }
+    }
+    SAState_p->CurrentOffset += 1;
+
+    /* Determine whether we will have a fixed sequence number offset */
+    if (SAParams_p->direction == SAB_DIRECTION_INBOUND &&
+        (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0||
+         SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+    {
+        /* Determine size of sequence number mask in bits */
+        if (SAParamsSSLTLS_p->SequenceMaskBitCount == 0)
+        {
+            if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_MASK_128) != 0)
+            {
+                SAParamsSSLTLS_p->SequenceMaskBitCount = 128;
+            }
+            else if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_MASK_32) != 0)
+            {
+                SAParamsSSLTLS_p->SequenceMaskBitCount = 32;
+            }
+            else
+            {
+                SAParamsSSLTLS_p->SequenceMaskBitCount = 64;
+            }
+        }
+        if (SAParamsSSLTLS_p->SequenceMaskBitCount > SAB_SEQUENCE_MAXBITS ||
+            (SAParamsSSLTLS_p->SequenceMaskBitCount & 0x1f) != 0)
+        {
+            LOG_CRIT("SABuilder: Illegal sequence mask size.\n");
+            return SAB_INVALID_PARAMETER;
+        }
+#ifdef SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+        fFixedSeqOffset = true;
+#else
+        if (SAParamsSSLTLS_p->SequenceMaskBitCount > 128 ||
+            (SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_FIXED_SEQ_OFFSET) != 0)
+        {
+            fFixedSeqOffset = true;
+        }
+#endif
+        if (SAParamsSSLTLS_p->SequenceMaskBitCount == 32)
+        {
+            fFixedSeqOffset = false; /* not supported for 32-bit mask */
+        }
+    }
+
+
+    if (fFixedSeqOffset)
+    {
+        /* Use a fixed sequence number offset for inbound if the hardware
+           supports it. */
+        /* Take care to insert the IV (nonce) just after the SPI. */
+        IVOffset = SAState_p->CurrentOffset;
+
+        /* Select one of two fixed offsets for the sequence number */
+        if (SAState_p->CurrentOffset < SAB_SEQNUM_LO_FIX_OFFSET)
+        {
+            SAState_p->CurrentOffset = SAB_SEQNUM_LO_FIX_OFFSET;
+        }
+        else
+        {
+            SAState_p->CurrentOffset = SAB_SEQNUM_HI_FIX_OFFSET;
+        }
+
+        /* Add sequence number */
+        SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+        SAParams_p->SeqNumWord32Count = 2;
+        SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+        SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_48_FIX;
+        if (SABuffer_p != NULL)
+        {
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->SeqNum;
+            SABuffer_p[SAState_p->CurrentOffset + 1] =
+                    (SAParamsSSLTLS_p->SeqNumHi & 0xffff) |
+                    (SAParamsSSLTLS_p->epoch << 16);
+        }
+        SAState_p->CurrentOffset += 2;
+    }
+    else
+    {
+        /* Add sequence number */
+        SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+        SAParams_p->SeqNumWord32Count = 2;
+        SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+
+        if (SABuffer_p != NULL)
+            SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->SeqNum;
+        SAState_p->CurrentOffset += 1;
+        if (SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_0 &&
+            SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2)
+        {
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64;
+            if (SABuffer_p != NULL)
+                SABuffer_p[SAState_p->CurrentOffset] =
+                    SAParamsSSLTLS_p->SeqNumHi;
+        }
+        else
+        {
+            SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_48;
+            if (SABuffer_p != NULL)
+                SABuffer_p[SAState_p->CurrentOffset] =
+                    (SAParamsSSLTLS_p->SeqNumHi & 0xffff) |
+                    (SAParamsSSLTLS_p->epoch << 16);
+        }
+        SAState_p->CurrentOffset += 1;
+    }
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+        else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM||
+                 SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+            SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+
+        /* Some versions of the hardware can update the sequence number
+           early, so multiple engines can operate in parallel. */
+        SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+        SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+
+        /* Take care of IV  */
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+        {
+            if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+            {
+                SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+                    SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+                SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2|
+                    SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+                if (SABuffer_p != NULL)
+                {
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->Nonce_p,
+                                            3 * sizeof(uint32_t));
+                    SABuffer_p[SAState_p->CurrentOffset + 3] =
+                        SAB_CCM_FLAG_L3 << 24;
+                }
+                SAState_p->CurrentOffset += 4;
+            }
+            else
+            {
+                SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+                    SAB_CW1_IV_ORIG_SEQ;
+                SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+                if (SABuffer_p != NULL)
+                {
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->Nonce_p,
+                                            sizeof(uint32_t));
+                    SABuffer_p[SAState_p->CurrentOffset + 1] =
+                        SAB_CCM_FLAG_L3 << 24;
+                }
+                SAState_p->CurrentOffset += 2;
+            }
+        }
+        else if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 ||
+                 SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+        {
+            SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+                SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+            SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+            /* Always store the nonce (implicit salt) with TLS1.3 */
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    SAState_p->CurrentOffset,
+                                    SAParams_p->Nonce_p, 3*sizeof(uint32_t));
+            SAState_p->CurrentOffset +=3;
+        }
+        else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+        {
+            if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+                SAParams_p->IVSrc = SAB_IV_SRC_SEQ;
+
+            if (SAParams_p->IVSrc == SAB_IV_SRC_SEQ)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+                SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+                if (SAParams_p->IV_p == NULL)
+                {
+                    LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                    return SAB_INVALID_PARAMETER;
+                }
+#endif
+                SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                SAParams_p->IVWord32Count = 2;
+
+                SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+                                        SAParams_p->IV_p, 8);
+                SAState_p->CurrentOffset += 2;
+            }
+            else
+            {
+                SAState_p->CW1 |= SAB_CW1_IV_CTR;
+            }
+            SAState_p->CW1 |= SAB_CW1_IV0;
+            /* Always store the nonce (implicit salt) with AES-GCM */
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    SAState_p->CurrentOffset,
+                                    SAParams_p->Nonce_p,
+                                    sizeof(uint32_t));
+            SAState_p->CurrentOffset +=1;
+            if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+            {
+                /* Store a fixed 8-byte value to XOR with sequence number */
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    SAState_p->CurrentOffset,
+                                    SAParams_p->IV_p,
+                                        2*sizeof(uint32_t));
+                SAState_p->CurrentOffset +=2;
+            }
+        }
+        else if (SAState_p->IVWords > 0)
+        { /* CBC mode, non-null */
+            if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+                SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0)
+            {
+                SAParams_p->IVSrc = SAB_IV_SRC_SA;
+                SAState_p->CW1 |= SAB_CW1_CRYPTO_STORE;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+            {
+                SAParams_p->IVSrc = SAB_IV_SRC_PRNG;
+            }
+            SAState_p->CW1 |= SAB_CW1_IV_FULL;
+            if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+            {
+                SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+                if(SAState_p->IVWords == 4)
+                    SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+                if (SAParams_p->IV_p == NULL)
+                {
+                    LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                    return SAB_INVALID_PARAMETER;
+                }
+#endif
+                SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+                SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+                SABuilderLib_CopyKeyMat(SABuffer_p,
+                                        SAState_p->CurrentOffset,
+                                        SAParams_p->IV_p,
+                                        SAState_p->IVWords * sizeof(uint32_t));
+                SAState_p->CurrentOffset += SAState_p->IVWords;
+            }
+        }
+    }
+    else
+    {   /* Inbound */
+        if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+        else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+                 SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+            SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+        else
+            SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+
+        if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+            SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+            SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20  &&
+            SAState_p->IVWords > 0)
+        {
+            SAState_p->CW1 |= SAB_CW1_PREPKT_OP;
+            if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0)
+            {
+                SAState_p->CW1 |= SAB_CW1_PAD_SSL;
+            }
+            else
+            {
+                SAState_p->CW1 |= SAB_CW1_PAD_TLS;
+            }
+        }
+        if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+        {
+            SAState_p->CW1 |= SAB_CW1_PAD_TLS | SAB_CW1_CRYPTO_AEAD;
+        }
+
+        /* Add sequence mask for DTLS only. */
+        if ((SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0 ||
+             SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+        {
+            unsigned int InputMaskWordCount =
+                SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+            unsigned int AllocMaskWordCount;
+            SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+            /* Determine the required hardware mask size in words and set
+               control words accordingly. */
+            if (InputMaskWordCount  == 1)
+            {
+                AllocMaskWordCount = 1;
+                SAState_p->CW0 |= SAB_CW0_MASK_32;
+            }
+            else if (InputMaskWordCount  == 2)
+            {
+                AllocMaskWordCount = 2;
+                if (fFixedSeqOffset)
+                {
+                    SAState_p->CW0 |= SAB_CW0_MASK_64_FIX;
+                }
+                else
+                {
+                    SAState_p->CW0 |= SAB_CW0_MASK_64;
+                }
+            }
+            else if (InputMaskWordCount <= 4)
+            {
+                AllocMaskWordCount = 4;
+                if (fFixedSeqOffset)
+                {
+                SAState_p->CW0 |= SAB_CW0_MASK_128_FIX;
+                }
+                else
+                {
+                SAState_p->CW0 |= SAB_CW0_MASK_128;
+                }
+            }
+#ifdef SAB_ENABLE_256BIT_SEQMASK
+            else if (InputMaskWordCount <= 8)
+            {
+                AllocMaskWordCount = 8;
+                SAState_p->CW0 |= SAB_CW0_MASK_256_FIX;
+            }
+#endif
+            else
+            {
+                AllocMaskWordCount = 12;
+                SAState_p->CW0 |= SAB_CW0_MASK_384_FIX;
+            }
+            if(SABuffer_p != NULL)
+            {
+                unsigned int i;
+                for (i = 0; i < InputMaskWordCount; i++)
+                    SABuffer_p[SAState_p->CurrentOffset+i] =
+                        SAParamsSSLTLS_p->SeqMask[i];
+                /* If the input mask is smaller than the one picked by the
+                   hardware, fill the remaining words with all-one, the
+                   hardware will treat these words as invalid.
+                */
+                for (i= InputMaskWordCount; i < AllocMaskWordCount; i++)
+                    SABuffer_p[SAState_p->CurrentOffset+i] = 0xffffffff;
+            }
+            SAState_p->CurrentOffset += AllocMaskWordCount;
+            SAParams_p->SeqMaskWord32Count = InputMaskWordCount;
+        }
+
+        if (IVOffset == 0)
+            IVOffset = SAState_p->CurrentOffset;
+        if (SAState_p->IVWords > 0 &&
+            (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+             SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0))
+        {
+            SAParams_p->IVSrc = SAB_IV_SRC_SA;
+            SAState_p->CW1 |= SAB_CW1_IV_FULL;
+
+            SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1 |
+                SAB_CW1_CRYPTO_STORE;
+            if(SAState_p->IVWords == 4)
+                    SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+            if (SAParams_p->IV_p == NULL)
+            {
+                LOG_CRIT("SABuilder: NULL pointer IV.\n");
+                    return SAB_INVALID_PARAMETER;
+            }
+#endif
+            SAParams_p->OffsetIV = IVOffset;
+            SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    IVOffset,
+                                    SAParams_p->IV_p,
+                                    SAState_p->IVWords * sizeof(uint32_t));
+            IVOffset += SAState_p->IVWords;
+        }
+
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+        {
+            if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+            {
+                SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+                    SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+                SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2|
+                    SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+                if (SABuffer_p != NULL)
+                {
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->Nonce_p,
+                                            3 * sizeof(uint32_t));
+                    SABuffer_p[SAState_p->CurrentOffset + 3] =
+                        SAB_CCM_FLAG_L3 << 24;
+                }
+                SAState_p->CurrentOffset += 4;
+            }
+            else
+            {
+                SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK);
+                SAState_p->CW1 |= SAB_CW1_IV0| SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+                if (SABuffer_p != NULL)
+                {
+                    SABuilderLib_CopyKeyMat(SABuffer_p,
+                                            SAState_p->CurrentOffset,
+                                            SAParams_p->Nonce_p,
+                                            sizeof(uint32_t));
+                    SABuffer_p[SAState_p->CurrentOffset + 1] =
+                        SAB_CCM_FLAG_L3 << 24;
+                }
+                SAState_p->CurrentOffset += 2;
+            }
+        }
+        else if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 ||
+            SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+        {
+
+            if (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2)
+            {
+                /* DTLS inbound extracts the sequence number from the packet, use delayed OTK mode */
+                SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+            } else {
+                /* regular TLS inbound internally increments the sequence number, so can save some cycles by starting OTK calc early */
+                SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+                    SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+            }
+            SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+            /* Always store the nonce (implicit salt) with TLS1.3 */
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    IVOffset,
+                                    SAParams_p->Nonce_p, 3*sizeof(uint32_t));
+            IVOffset +=3;
+        }
+        else if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+        {
+            SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_IV0;
+            /* Always store the nonce (implicit salt) with AES-GCM */
+            SABuilderLib_CopyKeyMat(SABuffer_p,
+                                    IVOffset,
+                                    SAParams_p->Nonce_p, sizeof(uint32_t));
+            IVOffset +=1;
+        }
+        if (IVOffset > SAState_p->CurrentOffset)
+        {
+            SAState_p->CurrentOffset = IVOffset;
+        }
+
+    }
+
+    return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_SSLTLS */
+
+/* end of file sa_builder_ssltls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c
new file mode 100644
index 0000000..16b039e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c
@@ -0,0 +1,1696 @@
+/* token_builder_context.c
+ *
+ * This is the main implementation module for the EIP-96 Token Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "token_builder.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_token_builder.h"
+#include "basic_defs.h"
+#include "clib.h"
+#include "log.h"
+#include "sa_builder_params.h"
+#include "sa_builder_params_ipsec.h"
+
+#include "token_builder_internal.h"
+#include "sa_builder_params.h"
+#ifdef TKB_ENABLE_PROTO_IPSEC
+#include "sa_builder_params_ipsec.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+#include "sa_builder_params_ssltls.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_BASIC
+#include "sa_builder_params_basic.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_SRTP
+#include "sa_builder_params_srtp.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_GetContextSize
+ *
+ * Determine the size of the token context record in 32-bit words, which may
+ * depend on the SA parameters.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure
+ * TokenContextWord32Count_p (output)
+ *   Required size of the Token Context Record in 32-bit words.
+ *
+ * Note: This implementation has one Token Context Record format with a fixed
+ *       size. Therefore this function does not look at the SA parameters.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the input data structures are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_GetContextSize(
+    const SABuilder_Params_t * const SAParams_p,
+    unsigned int * const TokenContextWord32Count_p
+    )
+{
+#ifdef TKB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || TokenContextWord32Count_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_GetContextSize: NULL pointer supplied\n");
+        return TKB_INVALID_PARAMETER;
+    }
+#endif
+    *TokenContextWord32Count_p =
+        ((unsigned int)sizeof(TokenBuilder_Context_t) +  sizeof(uint32_t) - 1) /
+        sizeof(uint32_t);
+    return TKB_STATUS_OK;
+}
+
+
+#ifdef TKB_ENABLE_PROTO_IPSEC
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_IPsec
+ *
+ * Fill in the context fields for extended IPsec operations.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_Internal_p (output)
+ *   Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_Extended(
+    const SABuilder_Params_t * const SAParams_p,
+    TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+    uint8_t HeaderProto;
+    SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+    SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = TKB_HDR_IPV6_OUT_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = TKB_HDR_IPV6_OUT_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS;
+            }
+        }
+        else
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = TKB_HDR_IPV4_OUT_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = TKB_HDR_IPV4_OUT_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS;
+            }
+        }
+
+    }
+    else
+    {
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                TokenContext_Internal_p->TokenHeaderWord |= TKB_HEADER_UPD_HDR;
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = TKB_HDR_IPV6_IN_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = TKB_HDR_IPV6_IN_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS;
+            }
+        }
+        else
+        {
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+            {
+                TokenContext_Internal_p->TokenHeaderWord |= TKB_HEADER_UPD_HDR;
+                if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+                {
+                    HeaderProto = TKB_HDR_IPV4_IN_TUNNEL;
+                }
+                else
+                {
+                    HeaderProto = TKB_HDR_IPV4_IN_TRANSP;
+                }
+            }
+            else
+            {
+                HeaderProto = TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS;
+            }
+        }
+
+    }
+    /* If NAT-T selected, select other header protocol range */
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+        HeaderProto += (TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT -
+                        TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS);
+
+    TokenContext_Internal_p->hproto = HeaderProto;
+
+    TokenContext_Internal_p->u.generic.TTL = SAParamsIPsec_p->TTL;
+    TokenContext_Internal_p->u.generic.DSCP = SAParamsIPsec_p->DSCP;
+    TokenContext_Internal_p->NATT_Ports =
+        (SAParamsIPsec_p->NATTSrcPort >> 8) |
+        ((SAParamsIPsec_p->NATTSrcPort & 0xff) << 8) |
+        ((SAParamsIPsec_p->NATTDestPort & 0xff00) << 8) |
+        ((SAParamsIPsec_p->NATTDestPort & 0xff) << 24 );
+
+    TokenContext_Internal_p->u.generic.ESPFlags = 0;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_DF) != 0)
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_CLEAR_DF;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_SET_DF) != 0)
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_SET_DF;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_REPLACE_DSCP) != 0)
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_REPLACE_DSCP;
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_ECN) != 0)
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_CLEAR_ECN;
+
+    if (HeaderProto == TKB_HDR_IPV4_OUT_TUNNEL ||
+        HeaderProto == TKB_HDR_IPV6_OUT_TUNNEL ||
+        HeaderProto == TKB_HDR_IPV4_OUT_TUNNEL_NATT ||
+        HeaderProto == TKB_HDR_IPV6_OUT_TUNNEL_NATT)
+    {
+        if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+            SAParamsIPsec_p->DestIPAddr_p == NULL)
+        {
+            LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) != 0)
+        {
+            memcpy(TokenContext_Internal_p->TunnelIP,
+                   SAParamsIPsec_p->SrcIPAddr_p,
+                   4);
+            memcpy(TokenContext_Internal_p->TunnelIP + 4,
+                   SAParamsIPsec_p->DestIPAddr_p,
+                   4);
+        }
+        else
+        {
+            memcpy(TokenContext_Internal_p->TunnelIP,
+                   SAParamsIPsec_p->SrcIPAddr_p,
+                   16);
+            memcpy(TokenContext_Internal_p->TunnelIP + 16,
+                   SAParamsIPsec_p->DestIPAddr_p,
+                   16);
+        }
+    }
+    else if ((HeaderProto == TKB_HDR_IPV4_OUT_TRANSP_NATT ||
+              HeaderProto == TKB_HDR_IPV4_IN_TRANSP_NATT) &&
+             (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) !=0)
+    {
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_NAT;
+        if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+            SAParamsIPsec_p->DestIPAddr_p == NULL)
+        {
+            LOG_CRIT("SABuilder: NULL pointer NAT address.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+        memcpy(TokenContext_Internal_p->TunnelIP,
+               SAParamsIPsec_p->SrcIPAddr_p,
+               4);
+        memcpy(TokenContext_Internal_p->TunnelIP + 4,
+               SAParamsIPsec_p->DestIPAddr_p,
+               4);
+    }
+    else if ((HeaderProto == TKB_HDR_IPV6_OUT_TRANSP_NATT ||
+              HeaderProto == TKB_HDR_IPV6_IN_TRANSP_NATT) &&
+             (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) !=0)
+    {
+        TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_NAT;
+        if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+            SAParamsIPsec_p->DestIPAddr_p == NULL)
+        {
+            LOG_CRIT("SABuilder: NULL pointer NAT address.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+        memcpy(TokenContext_Internal_p->TunnelIP,
+               SAParamsIPsec_p->SrcIPAddr_p,
+               16);
+        memcpy(TokenContext_Internal_p->TunnelIP + 16,
+               SAParamsIPsec_p->DestIPAddr_p,
+               16);
+    }
+    return TKB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_Next_PktId
+ *
+ * Increment the PktID if the Token Context describes an IPv4 ESP Tunnel
+ * operation
+ *
+ */
+unsigned int
+TokenBuilder_Next_PktId(
+    const void * const TokenContext_p,
+    unsigned int PktId)
+{
+    const TokenBuilder_Context_t * const TokenContext_Internal_p =
+        (const TokenBuilder_Context_t * const )TokenContext_p;
+    if (TokenContext_Internal_p->hproto == TKB_HDR_IPV4_OUT_TUNNEL ||
+        TokenContext_Internal_p->hproto == TKB_HDR_IPV4_OUT_TUNNEL_NATT)
+    {
+        return (PktId + 1) & MASK_16_BITS;
+    }
+    else
+    {
+        return PktId;
+    }
+}
+
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_IPsec
+ *
+ * Create a Token Context Record for IPsec.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_Internal_p (output)
+ *   Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_IPsec(
+    const SABuilder_Params_t * const SAParams_p,
+    TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+    SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+    SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsIPsec_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " IPsec extension pointer is NULL\n");
+        return TKB_INVALID_PARAMETER;
+    }
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+    {
+#ifdef TKB_ENABLE_IPSEC_ESP
+        TokenContext_Internal_p->ExtSeq = 0;
+        if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY) != 0)
+            TokenContext_Internal_p->AntiReplay = 0;
+        else
+            TokenContext_Internal_p->AntiReplay = 1;
+
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+        {
+            TokenContext_Internal_p->protocol = TKB_PROTO_ESP_OUT;
+            TokenContext_Internal_p->PadBlockByteCount = 4;
+            TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+                TokenContext_Internal_p->ExtSeq = 1;
+        }
+        else
+        {
+            TokenContext_Internal_p->protocol = TKB_PROTO_ESP_IN;
+            TokenContext_Internal_p->PadBlockByteCount = 4;
+            TokenContext_Internal_p->TokenHeaderWord |=
+                TKB_HEADER_PAD_VERIFY;
+            TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+            if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+                TokenContext_Internal_p->ExtSeq = 1;
+            if (TokenContext_Internal_p->ExtSeq == 0 &&
+                SAParams_p->OffsetSeqNum + 2 == SAParams_p->OffsetSeqMask &&
+                TokenContext_Internal_p->AntiReplay != 0)
+            {
+                TokenContext_Internal_p->ExtSeq = 2;
+                /* Special case, ExtSeq==2 do not use extended sequence
+                   number, but update context as if we have extended
+                   sequence number. Special SA format fixed seqnum/mask
+                   offsets.
+                */
+            }
+            TokenContext_Internal_p->AntiReplay *=
+                SAParamsIPsec_p->SequenceMaskBitCount / 32;
+        }
+        TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetSeqNum;
+
+        switch (SAParams_p->CryptoAlgo)
+        {
+        case SAB_CRYPTO_NULL:
+            TokenContext_Internal_p->IVByteCount = 0;
+            break;
+        case SAB_CRYPTO_DES:
+        case SAB_CRYPTO_3DES:
+            TokenContext_Internal_p->IVByteCount = 8;
+            TokenContext_Internal_p->PadBlockByteCount = 8;
+            break;
+        case SAB_CRYPTO_AES:
+        case SAB_CRYPTO_SM4:
+        case SAB_CRYPTO_BC0:
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC)
+            {
+                TokenContext_Internal_p->IVByteCount = 16;
+                TokenContext_Internal_p->PadBlockByteCount = 16;
+            }
+            else
+            {
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_OUTBOUND_CTR;
+                else
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_INBOUND_CTR;
+                if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+                    TokenContext_Internal_p->IVByteCount = 0;
+                else
+                    TokenContext_Internal_p->IVByteCount = 8;
+            }
+            break;
+        case SAB_CRYPTO_CHACHA20:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                TokenContext_Internal_p->IVHandling =
+                    TKB_IV_OUTBOUND_CTR;
+            else
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_INBOUND_CTR;
+            if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+                TokenContext_Internal_p->IVByteCount = 0;
+            else
+                TokenContext_Internal_p->IVByteCount = 8;
+            break;
+        default:
+            LOG_CRIT("TokenBuilder_BuildContext:"
+                     " unsupported crypto algorithm.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+
+        /* For all inbound and CTR mode outbound packets there is
+           only one supported way to obtain the IV, which is already
+           taken care of. Now handle outbound CBC. */
+        if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+           SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+           SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+        {
+            switch (SAParams_p->IVSrc)
+            {
+            case SAB_IV_SRC_DEFAULT:
+            case SAB_IV_SRC_PRNG:
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_PRNG;
+                break;
+            case SAB_IV_SRC_SA: /* No action required */
+                break;
+            case SAB_IV_SRC_TOKEN:
+                if (TokenContext_Internal_p->IVByteCount == 8)
+                {
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_OUTBOUND_TOKEN_2WORDS;
+                    TokenContext_Internal_p->TokenHeaderWord |=
+                        TKB_HEADER_IV_TOKEN_2WORDS;
+                }
+                else
+                {
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_OUTBOUND_TOKEN_4WORDS;
+                    TokenContext_Internal_p->TokenHeaderWord |=
+                        TKB_HEADER_IV_TOKEN_4WORDS;
+                }
+                break;
+            default:
+                LOG_CRIT("TokenBuilder_BuildContext:"
+                         "Unsupported IV source\n");
+                return TKB_INVALID_PARAMETER;
+            }
+        }
+
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+            SAParamsIPsec_p->PadAlignment >
+            TokenContext_Internal_p->PadBlockByteCount &&
+            SAParamsIPsec_p->PadAlignment <= 256)
+            TokenContext_Internal_p->PadBlockByteCount =
+                SAParamsIPsec_p->PadAlignment;
+
+        switch(SAParams_p->AuthAlgo)
+        {
+        case SAB_AUTH_NULL:
+            TokenContext_Internal_p->ICVByteCount = 0;
+            TokenContext_Internal_p->ExtSeq = 0;
+            break;
+        case SAB_AUTH_HMAC_MD5:
+        case SAB_AUTH_HMAC_SHA1:
+        case SAB_AUTH_AES_XCBC_MAC:
+        case SAB_AUTH_AES_CMAC_128:
+            TokenContext_Internal_p->ICVByteCount = 12;
+            break;
+        case SAB_AUTH_HMAC_SHA2_224:
+        case SAB_AUTH_HMAC_SHA2_256:
+        case SAB_AUTH_HMAC_SM3:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            break;
+        case SAB_AUTH_HMAC_SHA2_384:
+            TokenContext_Internal_p->ICVByteCount = 24;
+            break;
+        case SAB_AUTH_HMAC_SHA2_512:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            break;
+        case SAB_AUTH_AES_CCM:
+        case SAB_AUTH_AES_GCM:
+        case SAB_AUTH_AES_GMAC:
+            // All these protocols have a selectable ICV length.
+            if (SAParamsIPsec_p->ICVByteCount == 8 ||
+                SAParamsIPsec_p->ICVByteCount == 12 ||
+                SAParamsIPsec_p->ICVByteCount == 16)
+            {
+                TokenContext_Internal_p->ICVByteCount =
+                    SAParamsIPsec_p->ICVByteCount;
+            }
+            else
+            {
+                TokenContext_Internal_p->ICVByteCount = 16;
+            }
+            switch (SAParams_p->AuthAlgo)
+            {
+                /* These protocols need specialized protocol codes
+                   for the token generator.*/
+            case SAB_AUTH_AES_CCM:
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_CCM_OUT;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_CCM_IN;
+                }
+                TokenContext_Internal_p->u.generic.CCMSalt =
+                    (SAParams_p->Nonce_p[0] << 8) |
+                    (SAParams_p->Nonce_p[1] << 16) |
+                    (SAParams_p->Nonce_p[2] << 24) |
+                    TKB_CCM_FLAG_ADATA_L4 |
+                    ((TokenContext_Internal_p->ICVByteCount-2)*4);
+                break;
+            case SAB_AUTH_AES_GCM:
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GCM_OUT;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GCM_IN;
+                }
+                break;
+            case SAB_AUTH_AES_GMAC:
+                if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GMAC_OUT;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GMAC_IN;
+                }
+                break;
+            default:
+                ;
+            }
+            break;
+        case SAB_AUTH_POLY1305:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                TokenContext_Internal_p->protocol =
+                    TKB_PROTO_ESP_CHACHAPOLY_OUT;
+            }
+            else
+            {
+                TokenContext_Internal_p->protocol =
+                    TKB_PROTO_ESP_CHACHAPOLY_IN;
+            }
+            break;
+        default:
+            LOG_CRIT("TokenBuilder_BuildContext:"
+                     " unsupported authentication algorithm.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+#else /* TKB_ENABLE_IPSEC_ESP */
+        LOG_CRIT("TokenBuilder_BuildContext: ESP not supported\n");
+        return TKB_INVALID_PARAMETER;
+#endif /* TKB_ENABLE_IPSEC_ESP */
+    }
+    else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_AH) != 0)
+    {
+#ifdef TKB_ENABLE_IPSEC_AH
+
+#else /* TKB_ENABLE_IPSEC_AH */
+        LOG_CRIT("TokenBuilder_BuildContext: AH not supported\n");
+        return TKB_INVALID_PARAMETER;
+#endif /* TKB_ENABLE_IPSEC_AH */
+    }
+    else
+    {
+        LOG_CRIT("TokenBuilder_BuildContext: Neither ESP nor AH set\n");
+        return TKB_INVALID_PARAMETER;
+    }
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+    if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_EXT_PROCESSING) != 0)
+    {
+        TokenBuilder_Status_t Rc;
+
+        Rc = TokenBuilder_BuildContext_Extended(SAParams_p,
+                                                TokenContext_Internal_p);
+        return Rc;
+    }
+#endif
+    return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_SSLTLS
+ *
+ * Create a Token Context Record for SSL/TLS/DTLS
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_Internal_p (output)
+ *   Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_SSLTLS(
+    const SABuilder_Params_t * const SAParams_p,
+    TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+    SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p;
+    SAParamsSSLTLS_p = (SABuilder_Params_SSLTLS_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsSSLTLS_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " SSL/TLS extension pointer is NULL\n");
+        return TKB_INVALID_PARAMETER;
+    }
+
+    TokenContext_Internal_p->ExtSeq = 0;
+    TokenContext_Internal_p->AntiReplay = 1;
+    TokenContext_Internal_p->IVOffset = 0;
+    TokenContext_Internal_p->DigestWordCount = 0;
+    TokenContext_Internal_p->u.generic.ESPFlags = 0;
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+    {
+        TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_OUT;
+        TokenContext_Internal_p->PadBlockByteCount = 1;
+        TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+    }
+    else
+    {
+        TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_IN;
+        TokenContext_Internal_p->PadBlockByteCount = 1;
+        if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+            SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR)
+            TokenContext_Internal_p->TokenHeaderWord |=
+                TKB_HEADER_PAD_VERIFY;
+        TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+    }
+    TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetSeqNum;
+
+    switch (SAParams_p->CryptoAlgo)
+    {
+    case SAB_CRYPTO_NULL:
+        TokenContext_Internal_p->IVByteCount = 0;
+        TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+        break;
+    case SAB_CRYPTO_ARCFOUR:
+        TokenContext_Internal_p->IVByteCount = 0;
+        TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_ARC4;
+        TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIJPtr;
+        break;
+    case SAB_CRYPTO_DES:
+    case SAB_CRYPTO_3DES:
+        TokenContext_Internal_p->IVByteCount = 8;
+        TokenContext_Internal_p->PadBlockByteCount = 8;
+        TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV2;
+        TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+        break;
+    case SAB_CRYPTO_AES:
+    case SAB_CRYPTO_SM4:
+    case SAB_CRYPTO_BC0:
+        if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+        {
+            TokenContext_Internal_p->IVByteCount = 8;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+                if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_TLS13_GCM_OUT;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_SSLTLS_GCM_OUT;
+                }
+            }
+            else
+            {
+                TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+                if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_TLS13_GCM_IN;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_SSLTLS_GCM_IN;
+                }
+            }
+        }
+        else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+        {
+            TokenContext_Internal_p->IVByteCount = 8;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+                if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_TLS13_CCM_OUT;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_SSLTLS_CCM_OUT;
+                }
+            }
+            else
+            {
+                TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+                if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_TLS13_CCM_IN;
+                }
+                else
+                {
+                    TokenContext_Internal_p->protocol =
+                        TKB_PROTO_SSLTLS_CCM_IN;
+                }
+            }
+            if (SAParamsSSLTLS_p->ICVByteCount == 0)
+                TokenContext_Internal_p->ICVByteCount = 16;
+            else if (SAParamsSSLTLS_p->ICVByteCount == 8 ||
+                     SAParamsSSLTLS_p->ICVByteCount == 16)
+            {
+                TokenContext_Internal_p->ICVByteCount = SAParamsSSLTLS_p->ICVByteCount;
+            }
+            else
+            {
+                LOG_CRIT("TokenBuilder_BuildContext:"
+                         " TLS AES-CCM rquires tag length of 8 or 16\n");
+                return TKB_INVALID_PARAMETER;
+            }
+            TokenContext_Internal_p->u.generic.CCMSalt = TKB_CCM_FLAG_ADATA_L3 |
+                ((TokenContext_Internal_p->ICVByteCount-2)*4);
+        }
+        else
+        {
+            TokenContext_Internal_p->IVByteCount = 16;
+            TokenContext_Internal_p->PadBlockByteCount = 16;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV4;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+        }
+        break;
+    case SAB_CRYPTO_CHACHA20:
+        TokenContext_Internal_p->IVByteCount = 0;
+        TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+        if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+        {
+            if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_TLS13_CHACHAPOLY_OUT;
+            }
+            else
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_CHACHAPOLY_OUT;
+            }
+        }
+        else
+        {
+            if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_TLS13_CHACHAPOLY_IN;
+            }
+            else
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_CHACHAPOLY_IN;
+            }
+        }
+        break;
+    default:
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " unsupported crypto algorithm.\n");
+        return TKB_INVALID_PARAMETER;
+    }
+
+    /* For all inbound and ARCFOUR outbound packets there is
+       only one supported way to obtain the IV, which is already
+       taken care of. Now handle outbound CBC. */
+    if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+       SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+       SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {
+        switch (SAParams_p->IVSrc)
+        {
+        case SAB_IV_SRC_DEFAULT:
+        case SAB_IV_SRC_PRNG:
+            TokenContext_Internal_p->TokenHeaderWord |=
+                TKB_HEADER_IV_PRNG;
+            break;
+        case SAB_IV_SRC_SA: /* No action required */
+            break;
+        case SAB_IV_SRC_TOKEN:
+            if (TokenContext_Internal_p->IVByteCount == 8)
+            {
+                TokenContext_Internal_p->IVHandling =
+                    TKB_IV_OUTBOUND_TOKEN_2WORDS;
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_TOKEN_2WORDS;
+            }
+            else
+            {
+                TokenContext_Internal_p->IVHandling =
+                    TKB_IV_OUTBOUND_TOKEN_4WORDS;
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_TOKEN_4WORDS;
+            }
+            break;
+        default:
+            LOG_CRIT("TokenBuilder_BuildContext:"
+                     "Unsupported IV source\n");
+            return TKB_INVALID_PARAMETER;
+        }
+    }
+
+    /* In SSL and TLS1.0 the IV does not appear explicitly in the packet */
+    if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+        SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0)
+        TokenContext_Internal_p->IVByteCount = 0;
+    else if (TokenContext_Internal_p->u.generic.UpdateHandling == TKB_UPD_IV2 ||
+             TokenContext_Internal_p->u.generic.UpdateHandling == TKB_UPD_IV4)
+        TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_BLK;
+
+    /* Sequence numbers appear explicitly in the packet in DTLS */
+    if (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0 ||
+        SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2)
+    {
+        if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) != 0)
+            TokenContext_Internal_p->u.generic.ESPFlags |= TKB_DTLS_FLAG_CAPWAP;
+
+        if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_NO_ANTI_REPLAY) != 0)
+            TokenContext_Internal_p->ExtSeq = 1;
+        else
+            TokenContext_Internal_p->ExtSeq = 1 +
+                SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+#ifdef TKB_ENABLE_EXTENDED_DTLS
+        if ((SAParamsSSLTLS_p->SSLTLSFlags &  SAB_DTLS_EXT_PROCESSING) != 0)
+        {
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) != 0)
+                    TokenContext_Internal_p->hproto = TKB_HDR_IPV6_OUT_DTLS;
+                else
+                    TokenContext_Internal_p->hproto = TKB_HDR_IPV4_OUT_DTLS;
+            }
+            else
+            {
+                TokenContext_Internal_p->hproto = TKB_HDR_DTLS_UDP_IN;
+                if ((SAParamsSSLTLS_p->SSLTLSFlags &  SAB_DTLS_PLAINTEXT_HEADERS) != 0)
+                    TokenContext_Internal_p->u.generic.ESPFlags |= TKB_DTLS_FLAG_PLAINTEXT_HDR;
+            }
+        }
+#endif
+    }
+
+    /* Version field is not hashed in SSL 3.0. */
+    if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0)
+        TokenContext_Internal_p->AntiReplay = 0;
+
+
+    switch(SAParams_p->AuthAlgo)
+    {
+    case SAB_AUTH_HMAC_MD5:
+    case SAB_AUTH_SSLMAC_MD5:
+        TokenContext_Internal_p->ICVByteCount = 16;
+        break;
+    case SAB_AUTH_HMAC_SHA1:
+    case SAB_AUTH_SSLMAC_SHA1:
+        TokenContext_Internal_p->ICVByteCount = 20;
+        break;
+    case SAB_AUTH_HMAC_SHA2_224:
+        TokenContext_Internal_p->ICVByteCount = 28;
+        break;
+    case SAB_AUTH_HMAC_SHA2_256:
+    case SAB_AUTH_HMAC_SM3:
+        TokenContext_Internal_p->ICVByteCount = 32;
+        break;
+    case SAB_AUTH_HMAC_SHA2_384:
+        TokenContext_Internal_p->ICVByteCount = 48;
+        break;
+    case SAB_AUTH_HMAC_SHA2_512:
+        TokenContext_Internal_p->ICVByteCount = 64;
+        break;
+    case SAB_AUTH_AES_GCM:
+        TokenContext_Internal_p->ICVByteCount = 16;
+        break;
+    case SAB_AUTH_AES_CCM:
+        /* Was already set earlier */
+        break;
+    case SAB_AUTH_POLY1305:
+        TokenContext_Internal_p->ICVByteCount = 16;
+        break;
+    default:
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " unsupported authentication algorithm.\n");
+        return TKB_INVALID_PARAMETER;
+    }
+    if (SAParamsSSLTLS_p->ICVByteCount != 0 &&
+        SAParamsSSLTLS_p->ICVByteCount < TokenContext_Internal_p->ICVByteCount)
+    {
+        TokenContext_Internal_p->ICVByteCount = SAParamsSSLTLS_p->ICVByteCount;
+    }
+    return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_BASIC
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_Basic
+ *
+ * Create a Token Context Record for Basic crypto
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_Internal_p (output)
+ *   Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_Basic(
+    const SABuilder_Params_t * const SAParams_p,
+    TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+    SABuilder_Params_Basic_t *SAParamsBasic_p;
+    SAParamsBasic_p = (SABuilder_Params_Basic_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsBasic_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " Basic extension pointer is NULL\n");
+        return TKB_INVALID_PARAMETER;
+    }
+
+    TokenContext_Internal_p->ExtSeq = 0;
+    TokenContext_Internal_p->AntiReplay = 0;
+    TokenContext_Internal_p->IVOffset = 0;
+    TokenContext_Internal_p->SeqOffset = 0;
+    TokenContext_Internal_p->PadBlockByteCount = 1;
+    TokenContext_Internal_p->IVByteCount = 0;
+    TokenContext_Internal_p->ICVByteCount = 0;
+    TokenContext_Internal_p->DigestWordCount = 0;
+    TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+    TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+    TokenContext_Internal_p->u.generic.CCMSalt = 0;
+
+    if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {   /* Basic crypto */
+        if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+        {
+            TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CRYPTO;
+        }
+        else if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+        {
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HASHENC;
+            }
+            else
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_DECHASH;
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_PAD_VERIFY;
+            }
+        }
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+        else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+        {
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CHACHAPOLY_OUT;
+            }
+            else
+            {
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CHACHAPOLY_IN;
+            }
+        }
+#endif
+        else
+        {
+            TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CRYPTHASH;
+        }
+        switch (SAParams_p->CryptoAlgo)
+        {
+        case SAB_CRYPTO_ARCFOUR:
+            TokenContext_Internal_p->IVByteCount = 0;
+            if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATELESS)
+                TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_ARC4;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIJPtr;
+            break;
+        case SAB_CRYPTO_DES:
+        case SAB_CRYPTO_3DES:
+            TokenContext_Internal_p->IVByteCount = 8;
+            TokenContext_Internal_p->PadBlockByteCount = 8;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV2;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            break;
+        case SAB_CRYPTO_AES:
+        case SAB_CRYPTO_SM4:
+        case SAB_CRYPTO_BC0:
+            TokenContext_Internal_p->IVByteCount = 16;
+            TokenContext_Internal_p->PadBlockByteCount = 16;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV4;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+        case SAB_CRYPTO_KASUMI:
+            TokenContext_Internal_p->IVByteCount = 8;
+            TokenContext_Internal_p->PadBlockByteCount = 8;
+            TokenContext_Internal_p->IVHandling = TKB_IV_KASUMI_F8;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            break;
+        case SAB_CRYPTO_SNOW:
+            TokenContext_Internal_p->IVByteCount = 16;
+            TokenContext_Internal_p->PadBlockByteCount = 1;
+            TokenContext_Internal_p->IVHandling = TKB_IV_SNOW_UEA2;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            break;
+        case SAB_CRYPTO_ZUC:
+            TokenContext_Internal_p->IVByteCount = 16;
+            TokenContext_Internal_p->PadBlockByteCount = 1;
+            TokenContext_Internal_p->IVHandling = TKB_IV_ZUC_EEA3;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+            break;
+#endif
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+        case SAB_CRYPTO_CHACHA20:
+            TokenContext_Internal_p->IVByteCount = 16;
+            TokenContext_Internal_p->PadBlockByteCount = 1;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            break;
+#endif
+        default:
+            LOG_CRIT("TokenBuilder_BuildContext:"
+                     " unsupported crypto algorithm.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+
+        switch (SAParams_p->CryptoMode)
+        {
+        case SAB_CRYPTO_MODE_ECB:
+            TokenContext_Internal_p->IVByteCount = 0;
+            TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+            break;
+        case SAB_CRYPTO_MODE_BASIC:
+        case SAB_CRYPTO_MODE_CBC:
+        case SAB_CRYPTO_MODE_ICM:
+        case SAB_CRYPTO_MODE_CFB:
+        case SAB_CRYPTO_MODE_OFB:
+        case SAB_CRYPTO_MODE_XTS:
+        case SAB_CRYPTO_MODE_XTS_STATEFUL:
+        case SAB_CRYPTO_MODE_CHACHA_CTR32:
+        case SAB_CRYPTO_MODE_CHACHA_CTR64:
+            if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_BASIC)
+            {
+                TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+                if (SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI)
+                {
+                    TokenContext_Internal_p->IVByteCount = 0;
+                    TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+                    break;
+                }
+                else
+                {
+                    TokenContext_Internal_p->PadBlockByteCount = 1;
+                }
+            }
+            else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ICM)
+            {
+                TokenContext_Internal_p->PadBlockByteCount = 1;
+            }
+            else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS ||
+                     SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS_STATEFUL)
+            {
+                TokenContext_Internal_p->PadBlockByteCount = 1;
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_XTS_CRYPTO;
+            }
+
+            if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+            {
+                TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+                if (TokenContext_Internal_p->IVByteCount == 8)
+                {
+                    TokenContext_Internal_p->IVByteCount = 0;
+                    if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_COPY_TOKEN_2WORDS;
+                    else
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_OUTBOUND_TOKEN_2WORDS;
+                    TokenContext_Internal_p->TokenHeaderWord |=
+                        TKB_HEADER_IV_TOKEN_2WORDS;
+                }
+                else
+                {
+                    TokenContext_Internal_p->IVByteCount = 0;
+                    if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_COPY_TOKEN_4WORDS;
+                    else
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_OUTBOUND_TOKEN_4WORDS;
+                    TokenContext_Internal_p->TokenHeaderWord |=
+                        TKB_HEADER_IV_TOKEN_4WORDS;
+                }
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+            {
+                TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                    TokenContext_Internal_p->IVHandling = TKB_IV_COPY_CBC;
+                else
+                    TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+            }
+            else
+            {
+                if(SAParams_p->IVSrc ==  SAB_IV_SRC_PRNG)
+                {
+                    TokenContext_Internal_p->TokenHeaderWord |=
+                        TKB_HEADER_IV_PRNG;
+                    TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+                }
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                {
+                    if (TokenContext_Internal_p->IVByteCount==8)
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_OUTBOUND_2WORDS;
+                    else
+                        TokenContext_Internal_p->IVHandling =
+                            TKB_IV_OUTBOUND_4WORDS;
+                }
+                TokenContext_Internal_p->IVByteCount = 0;
+            }
+
+            break;
+        case SAB_CRYPTO_MODE_CTR:
+        case SAB_CRYPTO_MODE_CCM:
+        case SAB_CRYPTO_MODE_GCM:
+        case SAB_CRYPTO_MODE_GMAC:
+            TokenContext_Internal_p->PadBlockByteCount = 1;
+            TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+
+            if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+            {
+                TokenContext_Internal_p->IVByteCount = 0;
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_COPY_TOKEN_4WORDS;
+                else
+                    TokenContext_Internal_p->IVHandling =
+                        TKB_IV_OUTBOUND_TOKEN_4WORDS;
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_TOKEN_4WORDS;
+            }
+            else if (SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+            {
+                TokenContext_Internal_p->IVByteCount = 8;
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                    TokenContext_Internal_p->IVHandling = TKB_IV_COPY_CTR;
+                else
+                    TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+            }
+            else
+            {
+                TokenContext_Internal_p->IVByteCount = 0;
+                if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+                    TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+            }
+            break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+        case SAB_CRYPTO_MODE_F8:
+        case SAB_CRYPTO_MODE_UEA2:
+        case SAB_CRYPTO_MODE_EEA3:
+            TokenContext_Internal_p->PadBlockByteCount = 1;
+            TokenContext_Internal_p->u.generic.CCMSalt =
+                (SAParamsBasic_p->bearer << 3) |
+                (SAParamsBasic_p->direction<<2);
+            if (TokenContext_Internal_p->IVByteCount == 8)
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_TOKEN_2WORDS;
+            else
+                TokenContext_Internal_p->TokenHeaderWord |=
+                    TKB_HEADER_IV_TOKEN_4WORDS;
+            TokenContext_Internal_p->IVByteCount = 0;
+            break;
+#endif
+            default:
+                ;
+        }
+    }
+    else if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+    {
+        TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_BYPASS;
+    }
+    else if (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_HMAC_PRECOMPUTE &&
+             SAParams_p->OffsetDigest1 != 0)
+    {
+        TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HMAC_PRECOMPUTE;
+    }
+    else
+    {
+        TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HASH;
+    }
+    if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+    {   /* Basic hash */
+        if ((SAParams_p->flags & (SAB_FLAG_HASH_SAVE|
+                                      SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+        {
+            /* We intend to store the hash state.*/
+            TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetDigest0;
+        }
+        if(SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+        {
+            /* Use ExtSeq variable to specify that payload will be copied */
+            if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_PAYLOAD) == 0)
+                TokenContext_Internal_p->ExtSeq = 1;
+        }
+        else
+        {
+            /* Use ExtSeq variable to specify that header
+             * (authenticated data( will be copied */
+            if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_HEADER) == 0)
+                TokenContext_Internal_p->ExtSeq = 1;
+        }
+        switch(SAParams_p->AuthAlgo)
+        {
+        case SAB_AUTH_HASH_MD5:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 16 + 4;
+            break;
+        case SAB_AUTH_HMAC_MD5:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            break;
+        case SAB_AUTH_HASH_SHA1:
+            TokenContext_Internal_p->ICVByteCount = 20;
+            TokenContext_Internal_p->DigestWordCount = 16 + 5;
+            break;
+        case SAB_AUTH_HMAC_SHA1:
+            TokenContext_Internal_p->ICVByteCount = 20;
+            TokenContext_Internal_p->DigestWordCount = 5;
+            break;
+        case SAB_AUTH_HASH_SHA2_224:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            TokenContext_Internal_p->DigestWordCount = 16 + 8;
+            break;
+        case SAB_AUTH_HMAC_SHA2_224:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            TokenContext_Internal_p->DigestWordCount = 8;
+            break;
+        case SAB_AUTH_HASH_SHA2_256:
+        case SAB_AUTH_HASH_SM3:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            TokenContext_Internal_p->DigestWordCount = 16 + 8;
+            break;
+        case SAB_AUTH_HMAC_SHA2_256:
+        case SAB_AUTH_HMAC_SM3:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            TokenContext_Internal_p->DigestWordCount = 8;
+            break;
+        case SAB_AUTH_HASH_SHA2_384:
+            TokenContext_Internal_p->ICVByteCount = 64;
+            TokenContext_Internal_p->DigestWordCount = 16 + 16;
+            break;
+        case SAB_AUTH_HMAC_SHA2_384:
+            if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+                TokenContext_Internal_p->ICVByteCount = 48;
+            else
+                TokenContext_Internal_p->ICVByteCount = 64;
+            TokenContext_Internal_p->DigestWordCount = 16;
+            break;
+        case SAB_AUTH_HASH_SHA2_512:
+            TokenContext_Internal_p->ICVByteCount = 64;
+            TokenContext_Internal_p->DigestWordCount = 16 + 16;
+            break;
+        case SAB_AUTH_HMAC_SHA2_512:
+            TokenContext_Internal_p->ICVByteCount = 64;
+            TokenContext_Internal_p->DigestWordCount = 16;
+            break;
+        case SAB_AUTH_HASH_SHA3_224:
+        case SAB_AUTH_HMAC_SHA3_224:
+        case SAB_AUTH_KEYED_HASH_SHA3_224:
+            TokenContext_Internal_p->ICVByteCount = 28;
+            TokenContext_Internal_p->DigestWordCount = 7;
+            break;
+        case SAB_AUTH_HASH_SHA3_256:
+        case SAB_AUTH_HMAC_SHA3_256:
+        case SAB_AUTH_KEYED_HASH_SHA3_256:
+            TokenContext_Internal_p->ICVByteCount = 32;
+            TokenContext_Internal_p->DigestWordCount = 8;
+            break;
+        case SAB_AUTH_HASH_SHA3_384:
+        case SAB_AUTH_HMAC_SHA3_384:
+        case SAB_AUTH_KEYED_HASH_SHA3_384:
+            TokenContext_Internal_p->ICVByteCount = 48;
+            TokenContext_Internal_p->DigestWordCount = 12;
+            break;
+        case SAB_AUTH_HASH_SHA3_512:
+        case SAB_AUTH_HMAC_SHA3_512:
+        case SAB_AUTH_KEYED_HASH_SHA3_512:
+            TokenContext_Internal_p->ICVByteCount = 64;
+            TokenContext_Internal_p->DigestWordCount = 16;
+            break;
+
+        case SAB_AUTH_AES_XCBC_MAC:
+        case SAB_AUTH_AES_CMAC_128:
+        case SAB_AUTH_AES_CMAC_192:
+        case SAB_AUTH_AES_CMAC_256:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            break;
+        case SAB_AUTH_AES_CCM:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CCM_OUT;
+            else
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CCM_IN;
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            // Adjust byte count now as it influences the SALT value.
+            if (SAParamsBasic_p->ICVByteCount != 0 &&
+                SAParamsBasic_p->ICVByteCount <
+                TokenContext_Internal_p->ICVByteCount)
+                TokenContext_Internal_p->ICVByteCount =
+                    SAParamsBasic_p->ICVByteCount;
+            TokenContext_Internal_p->u.generic.CCMSalt =
+                (SAParams_p->Nonce_p[0] << 8) |
+                (SAParams_p->Nonce_p[1] << 16) |
+                (SAParams_p->Nonce_p[2] << 24) |
+                TKB_CCM_FLAG_ADATA_L4 |
+                ((TokenContext_Internal_p->ICVByteCount-2)*4);
+            break;
+        case SAB_AUTH_AES_GCM:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GCM_OUT;
+            else
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GCM_IN;
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            break;
+        case SAB_AUTH_AES_GMAC:
+            if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GMAC_OUT;
+            else
+                TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GMAC_IN;
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+        case SAB_AUTH_KASUMI_F9:
+            TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_KASUMI_HASH;
+            TokenContext_Internal_p->ICVByteCount = 4;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            TokenContext_Internal_p->u.generic.CCMSalt =
+                SAParamsBasic_p->fresh;
+            break;
+        case SAB_AUTH_SNOW_UIA2:
+            TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_SNOW_HASH;
+            TokenContext_Internal_p->ICVByteCount = 4;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            TokenContext_Internal_p->u.generic.CCMSalt =
+                SAParamsBasic_p->fresh;
+            break;
+        case SAB_AUTH_ZUC_EIA3:
+            TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_ZUC_HASH;
+            TokenContext_Internal_p->ICVByteCount = 4;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            TokenContext_Internal_p->u.generic.CCMSalt =
+                (SAParamsBasic_p->bearer << 3);
+            break;
+#endif
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+        case SAB_AUTH_KEYED_HASH_POLY1305:
+        case SAB_AUTH_POLY1305:
+            TokenContext_Internal_p->ICVByteCount = 16;
+            TokenContext_Internal_p->DigestWordCount = 4;
+            break;
+#endif
+        default:
+            LOG_CRIT("TokenBuilder_BuildContext:"
+                     " unsupported authentication algorithm.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+        if (SAParamsBasic_p->ICVByteCount != 0 &&
+            SAParamsBasic_p->ICVByteCount <
+            TokenContext_Internal_p->ICVByteCount)
+            TokenContext_Internal_p->ICVByteCount =
+                SAParamsBasic_p->ICVByteCount;
+        if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_EXTRACT_ICV) != 0 ||
+            ((SAParams_p->AuthAlgo == SAB_AUTH_AES_CCM ||
+                 SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM ||
+              SAParams_p->AuthAlgo == SAB_AUTH_AES_GMAC) &&
+             TokenContext_Internal_p->SeqOffset == 0))
+            TokenContext_Internal_p->AntiReplay =
+                TokenContext_Internal_p->ICVByteCount;
+    }
+    return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_SRTP
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_SRTP
+ *
+ * Create a Token Context Record for SRTP
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_Internal_p (output)
+ *   Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_SRTP(
+    const SABuilder_Params_t * const SAParams_p,
+    TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+    // Note: SRTP may not make use of the Token Context fields
+    // CW0, CW1 CCMAalt and UpdateHandling as they occupy the same
+    // space as the SaltKey fields.
+    SABuilder_Params_SRTP_t *SAParamsSRTP_p;
+    SAParamsSRTP_p = (SABuilder_Params_SRTP_t *)
+        (SAParams_p->ProtocolExtension_p);
+    if (SAParamsSRTP_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_BuildContext:"
+                 " SRTP extension pointer is NULL\n");
+        return TKB_INVALID_PARAMETER;
+    }
+
+    if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+        TokenContext_Internal_p->protocol = TKB_PROTO_SRTP_OUT;
+    else
+        TokenContext_Internal_p->protocol = TKB_PROTO_SRTP_IN;
+
+    TokenContext_Internal_p->ICVByteCount = SAParamsSRTP_p->ICVByteCount;
+
+    if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+    {
+        TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_TOKEN_SRTP;
+
+        TokenContext_Internal_p->IVByteCount = 16;
+        TokenContext_Internal_p->TokenHeaderWord |=
+            TKB_HEADER_IV_TOKEN_4WORDS;
+        if (SAParams_p->Nonce_p == NULL)
+        {
+            LOG_CRIT("TokenBuilder_BuildContext: NULL nonce pointer.\n");
+            return TKB_INVALID_PARAMETER;
+        }
+
+        TokenContext_Internal_p->u.srtp.SaltKey0 =
+            (SAParams_p->Nonce_p[0]) |
+            (SAParams_p->Nonce_p[1] << 8) |
+            (SAParams_p->Nonce_p[2] << 16) |
+            (SAParams_p->Nonce_p[3] << 24);
+        TokenContext_Internal_p->u.srtp.SaltKey1 =
+            (SAParams_p->Nonce_p[4]) |
+            (SAParams_p->Nonce_p[5] << 8) |
+            (SAParams_p->Nonce_p[6] << 16) |
+            (SAParams_p->Nonce_p[7] << 24);
+        TokenContext_Internal_p->u.srtp.SaltKey2 =
+            (SAParams_p->Nonce_p[8]) |
+            (SAParams_p->Nonce_p[9] << 8) |
+            (SAParams_p->Nonce_p[10] << 16) |
+            (SAParams_p->Nonce_p[11] << 24);
+        TokenContext_Internal_p->u.srtp.SaltKey3 =
+            (SAParams_p->Nonce_p[12]) |
+            (SAParams_p->Nonce_p[13] << 8);
+    }
+    else
+    {
+        TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+        TokenContext_Internal_p->IVByteCount = 0;
+    }
+
+    if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_SRTCP) != 0)
+    {
+        TokenContext_Internal_p->ExtSeq = 4;
+    }
+    else
+    {
+        TokenContext_Internal_p->ExtSeq = 0;
+    }
+
+    if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_INCLUDE_MKI) != 0)
+    {
+        TokenContext_Internal_p->AntiReplay = 4;
+    }
+    else
+    {
+        TokenContext_Internal_p->AntiReplay = 0;
+    }
+    return TKB_STATUS_OK;
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext
+ *
+ * Create a Token Context Record.
+ *
+ * SAParams_p (input)
+ *   Points to the SA parameters data structure. It is important that
+ *   SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ *   for this SA.
+ * TokenContext_p (output)
+ *   Buffer to hold the Token Context Record. It must point to a valid
+ *   storage buffer that is large enough to hold the Token
+ *   Context. Before calling this function, the application must call
+ *   TokeBuilder_GetContextSize() with the same SA parameters and
+ *   allocate a buffer of that size.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ *                      the contents of the SA parameters are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_BuildContext(
+    const SABuilder_Params_t * const SAParams_p,
+    void * const TokenContext_p
+    )
+{
+    TokenBuilder_Context_t *TokenContext_Internal_p =
+        (TokenBuilder_Context_t *)TokenContext_p;
+    TokenBuilder_Status_t Rc;
+#ifdef TKB_STRICT_ARGS_CHECK
+    if (SAParams_p == NULL || TokenContext_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_BuildContext: NULL pointer supplied\n");
+        return TKB_INVALID_PARAMETER;
+    }
+#endif
+
+    TokenContext_Internal_p->TokenHeaderWord = TKB_HEADER_DEFAULT;
+
+    TokenContext_Internal_p->u.generic.CW0 = SAParams_p->CW0;
+    TokenContext_Internal_p->u.generic.CW1 = SAParams_p->CW1;
+    TokenContext_Internal_p->hproto = TKB_HDR_BYPASS;
+    switch (SAParams_p->protocol)
+    {
+#ifdef TKB_ENABLE_PROTO_IPSEC
+    case SAB_PROTO_IPSEC:
+        Rc = TokenBuilder_BuildContext_IPsec(SAParams_p,
+                                             TokenContext_Internal_p);
+    break;
+#endif  /* TKB_ENABLE_PROTO_IPSEC */
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+    case SAB_PROTO_SSLTLS:
+        Rc = TokenBuilder_BuildContext_SSLTLS(SAParams_p,
+                                             TokenContext_Internal_p);
+    break;
+#endif
+#ifdef TKB_ENABLE_PROTO_BASIC
+    case SAB_PROTO_BASIC:
+        Rc = TokenBuilder_BuildContext_Basic(SAParams_p,
+                                             TokenContext_Internal_p);
+    break;
+#endif
+#ifdef TKB_ENABLE_PROTO_SRTP
+    case SAB_PROTO_SRTP:
+        Rc = TokenBuilder_BuildContext_SRTP(SAParams_p,
+                                             TokenContext_Internal_p);
+    break;
+#endif
+    default:
+        LOG_CRIT("TokenBuilder_BuildContext: unsupported protocol.\n");
+        return TKB_INVALID_PARAMETER;
+    }
+
+    if (Rc != TKB_STATUS_OK)
+    {
+        return Rc;
+    }
+
+    if (TokenContext_Internal_p->protocol != TKB_PROTO_BASIC_HMAC_PRECOMPUTE &&
+        SAParams_p->OffsetDigest1 != 0 &&
+        SAParams_p->AuthKey2_p == NULL)
+    {
+        /* HMAC key desired, but not supplied, convert context temporarily
+           to context prepare context. After the first token, the Token
+           Builder will switch it back */
+        TokenContext_Internal_p->protocol_next =
+            TokenContext_Internal_p->protocol;
+        TokenContext_Internal_p->hproto_next =
+            TokenContext_Internal_p->hproto;
+        TokenContext_Internal_p->IVHandling_next =
+            TokenContext_Internal_p->IVHandling;
+        TokenContext_Internal_p->HeaderWordFields_next =
+            (TokenContext_Internal_p->TokenHeaderWord >> 22) & MASK_8_BITS;
+        TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HMAC_CTXPREPARE;
+        TokenContext_Internal_p->hproto = TKB_HDR_BYPASS;
+        TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+        /* Clear fields in Token Header word, to prevent IV from token etc.*/
+        TokenContext_Internal_p->TokenHeaderWord &= 0xc03fffff;
+        TokenContext_Internal_p->DigestWordCount =
+            SAParams_p->OffsetDigest1 - SAParams_p->OffsetDigest0;
+        TokenContext_Internal_p->DigestOffset = SAParams_p->OffsetDigest0;
+    }
+
+    LOG_INFO("TokenBuilderBuildContext: created context, header word=%08x\n"
+             "  proto=%d hproto=%d padalign=%d ivsize=%d icvsize=%d\n"
+             "  seqoffset=%d extseq=%d antireplay=%d ivhandling=%d\n",
+             TokenContext_Internal_p->TokenHeaderWord,
+             TokenContext_Internal_p->protocol,
+             TokenContext_Internal_p->hproto,
+             TokenContext_Internal_p->PadBlockByteCount,
+             TokenContext_Internal_p->IVByteCount,
+             TokenContext_Internal_p->ICVByteCount,
+             TokenContext_Internal_p->SeqOffset,
+             TokenContext_Internal_p->ExtSeq,
+             TokenContext_Internal_p->AntiReplay,
+             TokenContext_Internal_p->IVHandling);
+
+    return TKB_STATUS_OK;
+}
+
+
+
+
+/* end of file token_builder_context.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c
new file mode 100644
index 0000000..1cdba87
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c
@@ -0,0 +1,5650 @@
+/* File token_builder_core.c
+   code generated by tbgen.py */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "token_builder.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "c_token_builder.h"
+#include "basic_defs.h"
+#include "clib.h"
+#include "token_builder_internal.h"
+#include "token_builder_macros.h"
+
+#include "log.h"
+
+TokenBuilder_Status_t
+TokenBuilder_GetSize(
+    const void * const TokenContext_p,
+    unsigned int * const TokenWord32Count_p
+    )
+{
+    TokenBuilder_Context_t ContextCopy;
+    TokenBuilder_Context_t *TokenContext_Internal_p = &ContextCopy;
+    unsigned int WordCountOld = 0;
+
+
+    uint32_t proto;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t hproto;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t seq_offset;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t ivlen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t icvlen;
+#endif
+    uint32_t ivhandling;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t extseq;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_SRTP == 1u || TKB_HAVE_PROTO_IPSEC == 1u
+    uint32_t antireplay;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t upd_handling;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t cipher_is_aes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t hstatelen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t capwap_out;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t is_nat;
+#endif
+
+#ifdef TKB_STRICT_ARGS_CHECK
+    if (TokenWord32Count_p == NULL || TokenContext_p == NULL)
+    {
+        LOG_CRIT("TokenBuilder_GetSize: NULL pointer supplied\n");
+        return TKB_INVALID_PARAMETER;
+    }
+#endif
+    memcpy(TokenContext_Internal_p, TokenContext_p, sizeof(ContextCopy));
+
+redo:
+    *TokenWord32Count_p = TKB_TOKEN_HEADER_WORD_COUNT;
+
+    *TokenWord32Count_p += 3u;
+    ivhandling = EVAL_ivhandling();
+    if (ivhandling >= 8u)
+    {
+        if (ivhandling < 10u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else if (ivhandling > 13u)
+        {
+            *TokenWord32Count_p += 4u;
+        }
+        else if (ivhandling == 10u)
+        {
+            *TokenWord32Count_p += 4u;
+        }
+        else if (ivhandling == 11u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 4u;
+        }
+    }
+    *TokenWord32Count_p += 1u;
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+    hproto = EVAL_hproto();
+    switch(hproto)
+    {
+    case 5: /* ipv4_out_transp */
+        *TokenWord32Count_p += 2u;
+        break;
+    case 1: /* ipv4_out_transp_nohdrproc */
+        *TokenWord32Count_p += 1u;
+        break;
+    case 11: /* ipv6_out_transp */
+        *TokenWord32Count_p += 5u;
+        break;
+    case 2: /* ipv4_out_tunnel */
+        *TokenWord32Count_p += 6u;
+        break;
+    case 7: /* ipv6_out_tunnel */
+        *TokenWord32Count_p += 11u;
+        break;
+    case 6: /* ipv4_in_transp */
+        *TokenWord32Count_p += 2u;
+        break;
+    case 3: /* ipv4_in_transp_nohdrproc */
+        *TokenWord32Count_p += 1u;
+        break;
+    case 12: /* ipv6_in_transp */
+        *TokenWord32Count_p += 5u;
+        break;
+    case 4: /* ipv4_in_tunnel */
+    case 8: /* ipv6_in_tunnel */
+    case 24: /* ipv4_in_tunnel_natt */
+    case 28: /* ipv6_in_tunnel_natt */
+        *TokenWord32Count_p += 2u;
+        break;
+    case 25: /* ipv4_out_transp_natt */
+        *TokenWord32Count_p += 1u;
+        is_nat = EVAL_is_nat();
+        if (is_nat != 0u)
+        {
+            *TokenWord32Count_p += 4u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 3u;
+        break;
+    case 31: /* ipv6_out_transp_natt */
+        *TokenWord32Count_p += 17u;
+        break;
+    case 22: /* ipv4_out_tunnel_natt */
+        *TokenWord32Count_p += 8u;
+        break;
+    case 27: /* ipv6_out_tunnel_natt */
+        *TokenWord32Count_p += 13u;
+        break;
+    case 26: /* ipv4_in_transp_natt */
+        *TokenWord32Count_p += 1u;
+        is_nat = EVAL_is_nat();
+        if (is_nat != 0u)
+        {
+            *TokenWord32Count_p += 5u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 1u;
+        break;
+    case 32: /* ipv6_in_transp_natt */
+        *TokenWord32Count_p += 15u;
+        break;
+    case 13: /* ipv4_out_dtls */
+        *TokenWord32Count_p += 5u;
+        break;
+    case 33: /* ipv6_out_dtls */
+        *TokenWord32Count_p += 5u;
+        break;
+    }
+#endif
+#endif
+    proto = EVAL_proto();
+    switch(proto)
+    {
+    case 0: /* esp_out */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (ivhandling == 2u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 1u;
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq == 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 2u;
+            }
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 2u;
+#else
+#endif
+        break;
+    case 1: /* esp_in */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_ECN_FIXUP == 1u
+        *TokenWord32Count_p += 1u;
+#endif
+        if (ivhandling == 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq != 1u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 2u;
+            }
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+#else
+#endif
+        break;
+    case 2: /* esp_out_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        *TokenWord32Count_p += 5u;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 3u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 5u;
+        }
+        *TokenWord32Count_p += 9u;
+#else
+#endif
+        break;
+    case 3: /* esp_in_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        *TokenWord32Count_p += 7u;
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            *TokenWord32Count_p += 3u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 5u;
+        }
+        *TokenWord32Count_p += 1u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        *TokenWord32Count_p += 1u;
+#endif
+        *TokenWord32Count_p += 4u;
+#else
+#endif
+        break;
+    case 4: /* esp_out_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 3u;
+        }
+        *TokenWord32Count_p += 8u;
+#else
+#endif
+        break;
+    case 5: /* esp_in_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 4u;
+        }
+        *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        *TokenWord32Count_p += 1u;
+#endif
+        *TokenWord32Count_p += 3u;
+#else
+#endif
+        break;
+    case 6: /* esp_out_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 3u;
+        }
+        *TokenWord32Count_p += 8u;
+#else
+#endif
+        break;
+    case 7: /* esp_in_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 4u;
+        }
+        *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        *TokenWord32Count_p += 1u;
+#endif
+        *TokenWord32Count_p += 3u;
+#else
+#endif
+        break;
+    case 8: /* ssltls_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 3u;
+        antireplay = EVAL_antireplay();
+        if (antireplay != 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 6u;
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            *TokenWord32Count_p += 3u;
+            break;
+        case 1: /* upd_arc4 */
+            *TokenWord32Count_p += 4u;
+            break;
+        case 2: /* upd_iv2 */
+            *TokenWord32Count_p += 1u;
+            if (antireplay != 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            *TokenWord32Count_p += 2u;
+            break;
+        case 3: /* upd_iv4 */
+            *TokenWord32Count_p += 1u;
+            if (antireplay != 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            *TokenWord32Count_p += 2u;
+            break;
+        case 4: /* upd_blk */
+            *TokenWord32Count_p += 4u;
+            break;
+        }
+#else
+#endif
+        break;
+    case 9: /* ssltls_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        upd_handling = EVAL_upd_handling();
+        if (upd_handling <= 1u)
+        {
+            *TokenWord32Count_p += 3u;
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                *TokenWord32Count_p += 7u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 2u;
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 2u;
+                }
+                *TokenWord32Count_p += 2u;
+            }
+            *TokenWord32Count_p += 3u;
+            switch(upd_handling)
+            {
+            case 0: /* upd_null */
+                *TokenWord32Count_p += 1u;
+                if (extseq == 0u)
+                {
+                    *TokenWord32Count_p += 2u;
+                }
+                else if (extseq == 1u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 2u;
+                }
+                break;
+            case 1: /* upd_arc4 */
+                *TokenWord32Count_p += 5u;
+                break;
+            }
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+            cipher_is_aes = EVAL_cipher_is_aes();
+            if (cipher_is_aes == 0u)
+            {
+                *TokenWord32Count_p += 6u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 10u;
+            }
+            *TokenWord32Count_p += 3u;
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                *TokenWord32Count_p += 6u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 3u;
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                *TokenWord32Count_p += 1u;
+            }
+            *TokenWord32Count_p += 1u;
+            ivlen = EVAL_ivlen();
+            if (ivlen > 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            *TokenWord32Count_p += 3u;
+            switch(upd_handling)
+            {
+            case 2: /* upd_iv2 */
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                *TokenWord32Count_p += 2u;
+                break;
+            case 3: /* upd_iv4 */
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                *TokenWord32Count_p += 2u;
+                break;
+            case 4: /* upd_blk */
+                if (extseq == 0u)
+                {
+                    *TokenWord32Count_p += 2u;
+                }
+                else if (extseq == 1u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 2u;
+                }
+                break;
+            }
+        }
+#else
+#endif
+        break;
+    case 21: /* ssltls_gcm_out */
+    case 37: /* ssltls_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 4u;
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 5u;
+        if (proto != 37u)
+        {
+            if (extseq != 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 4u;
+#else
+#endif
+        break;
+    case 22: /* ssltls_gcm_in */
+    case 38: /* ssltls_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 11u;
+        if (proto != 38u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+            *TokenWord32Count_p += 1u;
+#else
+            *TokenWord32Count_p += 1u;
+#endif
+        }
+        *TokenWord32Count_p += 2u;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else if (extseq == 1u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+#else
+#endif
+        break;
+    case 10: /* basic_crypto */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 1: /* iv_inbound_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 4: /* iv_copy_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+        *TokenWord32Count_p += 2u;
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 1: /* upd_arc4 */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 2: /* upd_iv2 */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 3: /* upd_iv4 */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+#else
+#endif
+        break;
+    case 11: /* basic_hash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 2u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+            hstatelen = EVAL_hstatelen();
+            if (hstatelen > 16u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+        }
+#else
+#endif
+        break;
+    case 14: /* basic_crypthash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 1: /* iv_inbound_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 4: /* iv_copy_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+        *TokenWord32Count_p += 4u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+            hstatelen = EVAL_hstatelen();
+            if (hstatelen > 16u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+        }
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 1: /* upd_arc4 */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 2: /* upd_iv2 */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 3: /* upd_iv4 */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+#else
+#endif
+        break;
+    case 15: /* basic_out_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 2u;
+        if (ivhandling == 5u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 25u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+#else
+#endif
+        break;
+    case 16: /* basic_in_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 2u;
+        if (ivhandling == 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 25u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+#else
+#endif
+        break;
+    case 17: /* basic_out_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        default:
+            *TokenWord32Count_p += 1u;
+            ;
+        }
+        *TokenWord32Count_p += 2u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+#else
+#endif
+        break;
+    case 18: /* basic_in_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 2u;
+            break;
+        default:
+            *TokenWord32Count_p += 1u;
+            ;
+        }
+        *TokenWord32Count_p += 2u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+#else
+#endif
+        break;
+    case 19: /* basic_out_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        default:
+            *TokenWord32Count_p += 2u;
+            ;
+        }
+        *TokenWord32Count_p += 1u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+#else
+#endif
+        break;
+    case 20: /* basic_in_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        case 5: /* iv_copy_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            *TokenWord32Count_p += 3u;
+            break;
+        default:
+            *TokenWord32Count_p += 2u;
+            ;
+        }
+        *TokenWord32Count_p += 1u;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+#else
+#endif
+        break;
+    case 23: /* basic_xts_crypto */
+#if TKB_HAVE_CRYPTO_XTS == 1u
+        *TokenWord32Count_p += 5u;
+        switch(ivhandling)
+        {
+        case 1: /* iv_inbound_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 4: /* iv_copy_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+        *TokenWord32Count_p += 2u;
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 3: /* upd_iv4 */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+#else
+#endif
+        break;
+    case 24: /* basic_kasumi_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+        *TokenWord32Count_p += 3u;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 2u;
+#else
+#endif
+        break;
+    case 25: /* basic_snow_hash */
+    case 26: /* basic_zuc_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+        *TokenWord32Count_p += 5u;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 2u;
+#else
+#endif
+        break;
+    case 27: /* basic_hashenc */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 17u;
+        switch(ivhandling)
+        {
+        case 4: /* iv_copy_cbc */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            *TokenWord32Count_p += 1u;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            *TokenWord32Count_p += 1u;
+            break;
+        }
+        *TokenWord32Count_p += 3u;
+#else
+#endif
+        break;
+    case 28: /* basic_dechash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 1u;
+        cipher_is_aes = EVAL_cipher_is_aes();
+        if (cipher_is_aes == 0u)
+        {
+            *TokenWord32Count_p += 6u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 10u;
+        }
+        *TokenWord32Count_p += 21u;
+        ivlen = EVAL_ivlen();
+        if (ivlen > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 4u;
+#else
+#endif
+        break;
+    case 12: /* srtp_out */
+#if TKB_HAVE_PROTO_SRTP == 1u
+        *TokenWord32Count_p += 2u;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 1u;
+        antireplay = EVAL_antireplay();
+        if (antireplay > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 1u;
+#else
+#endif
+        break;
+    case 13: /* srtp_in */
+#if TKB_HAVE_PROTO_SRTP == 1u
+        *TokenWord32Count_p += 2u;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        antireplay = EVAL_antireplay();
+        if (antireplay > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            *TokenWord32Count_p += 1u;
+            if (antireplay > 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+            else
+            {
+                *TokenWord32Count_p += 1u;
+            }
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+            if (antireplay > 0u)
+            {
+                *TokenWord32Count_p += 1u;
+            }
+        }
+#else
+#endif
+        break;
+    case 29: /* basic_out_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+        *TokenWord32Count_p += 19u;
+#else
+#endif
+#else
+#endif
+        break;
+    case 30: /* basic_in_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+        *TokenWord32Count_p += 17u;
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+        *TokenWord32Count_p += 1u;
+#else
+        *TokenWord32Count_p += 1u;
+#endif
+        *TokenWord32Count_p += 3u;
+#else
+#endif
+#else
+#endif
+        break;
+    case 31: /* tls13_gcm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 12u;
+#else
+#endif
+        break;
+    case 32: /* tls13_gcm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 7u;
+#else
+#endif
+        break;
+    case 33: /* tls13_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 10u;
+#else
+#endif
+        break;
+    case 34: /* tls13_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 6u;
+#else
+#endif
+        break;
+    case 35: /* esp_out_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 3u;
+        }
+        *TokenWord32Count_p += 6u;
+#else
+#endif
+        break;
+    case 36: /* esp_in_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+            *TokenWord32Count_p += 1u;
+#endif
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 5u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+            *TokenWord32Count_p += 1u;
+#endif
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+            *TokenWord32Count_p += 1u;
+#else
+            *TokenWord32Count_p += 1u;
+#endif
+        }
+        *TokenWord32Count_p += 2u;
+#else
+#endif
+        break;
+    case 39: /* ssltls_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 1u;
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 11u;
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        *TokenWord32Count_p += 6u;
+        if (extseq != 0u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        *TokenWord32Count_p += 6u;
+#else
+#endif
+        break;
+    case 40: /* ssltls_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 24u;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            *TokenWord32Count_p += 2u;
+        }
+        else if (extseq == 1u)
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        else
+        {
+            *TokenWord32Count_p += 2u;
+        }
+#else
+#endif
+        break;
+    case 41: /* tls13_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 19u;
+#else
+#endif
+        break;
+    case 42: /* tls13_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        *TokenWord32Count_p += 14u;
+#else
+#endif
+        break;
+    case 43: /* basic_hmac_precompute */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 4u;
+#else
+#endif
+        break;
+    case 44: /* basic_hmac_ctxprepare */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        *TokenWord32Count_p += 6u;
+#else
+#endif
+        break;
+    case 45: /* basic_bypass */
+        *TokenWord32Count_p += 1u;
+        break;
+    default:
+        ;
+    }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+    hproto = EVAL_hproto();
+    switch(hproto)
+    {
+    case 6: /* ipv4_in_transp */
+    case 26: /* ipv4_in_transp_natt */
+        *TokenWord32Count_p += 1u;
+        break;
+    case 12: /* ipv6_in_transp */
+    case 32: /* ipv6_in_transp_natt */
+        *TokenWord32Count_p += 2u;
+        break;
+    }
+#endif
+    switch(proto)
+    {
+    case 1: /* esp_in */
+    case 3: /* esp_in_ccm */
+    case 5: /* esp_in_gcm */
+    case 7: /* esp_in_gmac */
+    case 36: /* esp_in_chachapoly */
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            antireplay = EVAL_antireplay();
+            if (antireplay > 12u)
+            {
+                *TokenWord32Count_p += 1u;
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+            }
+            else if (antireplay != 0u)
+            {
+                *TokenWord32Count_p += 1u;
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+                else
+                {
+                    *TokenWord32Count_p += 1u;
+                }
+            }
+            else
+            {
+                *TokenWord32Count_p += 1u;
+            }
+        }
+        else
+        {
+            *TokenWord32Count_p += 1u;
+        }
+        break;
+    }
+#endif
+
+
+    if (Switch_Proto(TokenContext_Internal_p))
+    {
+        /* Protocol was switched (HMAC context prepare to original protocol),
+           redo size computation with original protocol.*/
+        WordCountOld = *TokenWord32Count_p;
+        goto redo;
+    }
+    *TokenWord32Count_p = MAX(*TokenWord32Count_p, WordCountOld);
+
+   return TKB_STATUS_OK;
+}
+
+
+TokenBuilder_Status_t
+TokenBuilder_BuildToken(
+    void * const TokenContext_p,
+    const uint8_t *const Packet_p,
+    const uint32_t PacketByteCount,
+    TokenBuilder_Params_t * const TKBParams_p,
+    void * const Token_p,
+    uint32_t * const TokenWord32Count_p,
+    uint32_t * const TokenHeaderWord_p)
+{
+    uint32_t *tp = (uint32_t*)Token_p;
+    uint32_t rc = TKB_STATUS_OK;
+    TokenBuilder_Context_t *TokenContext_Internal_p =
+        (TokenBuilder_Context_t*)TokenContext_p;
+    uint32_t proto;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t hproto;
+#endif
+    uint32_t packetsize;
+    uint32_t bypass;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t nextheader;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u
+    uint32_t pad_remainder;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u
+    uint32_t pad_blocksize;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t pad_bytes;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t seq_offset;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t iv_offset;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t digest_offset;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t ivlen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t icvlen;
+#endif
+    uint32_t ivhandling;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t extseq;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t salt;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t basic_salt;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t paylen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swaplen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swap_fraglen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swap_fraglen_tls13;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swaplen3;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swaplen3_tls13_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t swaplen3_tls13_in;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t hashpad_tls13_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t hashpad_tls13_in;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t hashpad;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t aadlen_pkt;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t aadlen_tkn;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t aadlen_out;
+#endif
+#if TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t swap_j;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t basic_swaplen;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t aadlen_swap;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t aadpad;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t basic_hashpad;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u || TKB_HAVE_PROTO_IPSEC == 1u
+    uint32_t antireplay;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t upd_handling;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t cipher_is_aes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u
+    uint32_t appendhash;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+    uint32_t pad_bytes_basic;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t hstatelen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t capwap_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t capwap_in;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t hstatelen_bytes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    uint32_t pad_bytes_hashenc;
+#endif
+#if TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t srtp_offset;
+#endif
+#if TKB_HAVE_PROTO_SRTP == 1u
+    uint32_t srtp_swaproc;
+#endif
+    uint32_t srtp_iv0;
+    uint32_t srtp_iv1;
+    uint32_t srtp_iv2;
+    uint32_t srtp_iv3;
+    uint32_t count;
+    uint32_t bearer_dir_fresh;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t prev_nhoffset;
+#endif
+    uint32_t hdrlen;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u) || TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+    uint32_t ohdrlen;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t outlen;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t nh;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t is_nat;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t tunnel_w0_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t tunnel_w1_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t tunnel_w2_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t tunnel_w0_ip6;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t tunnel_w1_ip6;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    const uint8_t *tunnel_ip_addr;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    const uint8_t *dst_ip_addr;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+    uint32_t ports_natt;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_ECN_FIXUP == 1u)
+    uint32_t ecn_fixup_instr;
+#endif
+    uint32_t per_packet_options;
+    uint32_t u_word;
+    uint32_t cw0;
+    uint32_t cw1;
+    const uint8_t *iv;
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    const uint8_t *ssltls_lastblock;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+    const uint8_t *ssltls_lastword;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+    const uint8_t *aad;
+#endif
+
+    IDENTIFIER_NOT_USED(Packet_p);
+#ifdef TKB_STRICT_ARGS_CHECK
+    if (Token_p == NULL ||
+        TokenWord32Count_p == NULL ||
+        (TokenHeaderWord_p == NULL && TKB_TOKEN_HEADER_WORD_COUNT == 0))
+    {
+        LOG_CRIT("TokenBuilder: NULL pointer supplied\n");
+        return TKB_INVALID_PARAMETER;
+    }
+#endif
+    if (TokenContext_p == NULL)
+    {
+        rc = TKB_ERROR;
+        TKBParams_p->CLE = 2;
+        goto error;
+    }
+
+    if (TokenHeaderWord_p != NULL)
+        *TokenHeaderWord_p = EVAL_TokenHeaderWord();
+#if TKB_TOKEN_HEADER_WORD_COUNT > 0
+    {
+        unsigned int i;
+        *tp++ = EVAL_TokenHeaderWord();
+        for (i = 0; i < TKB_TOKEN_HEADER_WORD_COUNT - 1; i++)
+        {
+            *tp++ = 0;
+        }
+    }
+#endif
+
+    per_packet_options = EVAL_per_packet_options();
+    if (per_packet_options != 0u)
+    {
+        /* DATA32 cw0 + per_packet_options */
+        cw0 = EVAL_cw0();
+        *tp++=0x00000000 | ((cw0+per_packet_options)&0xffffffffu)<<0;
+        /* DATA32 cw1 */
+        cw1 = EVAL_cw1();
+        *tp++=0x00000000 | ((cw1)&0xffffffffu)<<0;
+    }
+    bypass = EVAL_bypass();
+    hdrlen = EVAL_hdrlen();
+    if (hdrlen == 4294967295u)
+    {
+        LOG_WARN("TokenBuilder: bad packet, ip header parse error\n");
+        rc = TKB_BAD_PACKET; goto error;
+    }
+    proto = EVAL_proto();
+    u_word = EVAL_u_word();
+    if (u_word != 0u)
+    {
+        /* DATA32 u_word */
+        *tp++=0x00000000 | ((u_word)&0xffffffffu)<<0;
+    }
+    ivhandling = EVAL_ivhandling();
+    if (ivhandling >= 8u)
+    {
+        if (ivhandling < 10u)
+        {
+            iv = EVAL_iv();
+            TokenBuilder_CopyBytes(tp, iv, 8);
+            tp += 2;
+        }
+        else if (ivhandling > 13u)
+        {
+            iv = EVAL_iv();
+            TokenBuilder_CopyBytes(tp, iv, 16);
+            tp += 4;
+        }
+        else if (ivhandling == 10u)
+        {
+            /* DATA32 srtp_iv0 */
+            srtp_iv0 = EVAL_srtp_iv0();
+            *tp++=0x00000000 | ((srtp_iv0)&0xffffffffu)<<0;
+            /* DATA32 srtp_iv1 */
+            srtp_iv1 = EVAL_srtp_iv1();
+            *tp++=0x00000000 | ((srtp_iv1)&0xffffffffu)<<0;
+            /* DATA32 srtp_iv2 */
+            srtp_iv2 = EVAL_srtp_iv2();
+            *tp++=0x00000000 | ((srtp_iv2)&0xffffffffu)<<0;
+            /* DATA32 srtp_iv3 */
+            srtp_iv3 = EVAL_srtp_iv3();
+            *tp++=0x00000000 | ((srtp_iv3)&0xffffffffu)<<0;
+        }
+        else if (ivhandling == 11u)
+        {
+            /* DATA32 count */
+            count = EVAL_count();
+            *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+            /* DATA32 bearer_dir_fresh */
+            bearer_dir_fresh = EVAL_bearer_dir_fresh();
+            *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+        }
+        else
+        {
+            /* DATA32 count */
+            count = EVAL_count();
+            *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+            /* DATA32 bearer_dir_fresh */
+            bearer_dir_fresh = EVAL_bearer_dir_fresh();
+            *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+            /* DATA32 count */
+            *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+            /* DATA32 bearer_dir_fresh */
+            *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+        }
+    }
+    if (bypass > 0u)
+    {
+        if (proto != 9u)
+        {
+            if (proto != 28u)
+            {
+                /* DIR OUT,bypass */
+                *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+            }
+        }
+    }
+    packetsize = EVAL_packetsize();
+    if (packetsize > 131071u)
+    {
+        LOG_WARN("TokenBuilder: bad packet, too long\n");
+        rc = TKB_BAD_PACKET; goto error;
+    }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+    hproto = EVAL_hproto();
+    switch(hproto)
+    {
+    case 5: /* ipv4_out_transp */
+        /* IPV4CHK OUT,50,outlen */
+        outlen = EVAL_outlen();
+        *tp++=0x61000000 | ((50u)&0xffu)<<16 | ((outlen)&0xffffu)<<0;
+        /* DIR OUT,hdrlen-12 */
+        *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+        break;
+    case 1: /* ipv4_out_transp_nohdrproc */
+        /* DIR OUT,hdrlen */
+        *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+        break;
+    case 11: /* ipv6_out_transp */
+        if (hdrlen > 40u)
+        {
+            /* IPV6 OUT,nh,outlen-40 */
+            nh = EVAL_nh();
+            outlen = EVAL_outlen();
+            *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((-40u+outlen)&0xffffu)<<0;
+            /* DIR OUT,prev_nhoffset-8    ; -8 to include two 32-bit words of the IPv6 header passed via IPV6 instruction */
+            prev_nhoffset = EVAL_prev_nhoffset();
+            *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+            /* REPL OUT,ORIG_TOKEN,1                ; replace NH byte of the last extension header with ESP type */
+            *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+            /* DATA32 50                            ; ESP proto */
+            *tp++=0x00000000 | ((50u)&0xffffffffu)<<0;
+            /* DIR OUT,hdrlen-prev_nhoffset-1    ; bypass the rest of the last extension header */
+            *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* IPV6 OUT,50,outlen-hdrlen */
+            outlen = EVAL_outlen();
+            *tp++=0x81000000 | ((50u)&0xffu)<<16 | ((outlen-hdrlen)&0xffffu)<<0;
+            /* DIR OUT,hdrlen-8 */
+            *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+        }
+        break;
+    case 2: /* ipv4_out_tunnel */
+        /* INS OUT,ORIG_TOKEN,20 */
+        *tp++=0x21d80000 | ((20u)&0x1ffffu)<<0;
+        /* DATA32 tunnel_w0_ip4 */
+        tunnel_w0_ip4 = EVAL_tunnel_w0_ip4();
+        *tp++=0x00000000 | ((tunnel_w0_ip4)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w1_ip4 */
+        tunnel_w1_ip4 = EVAL_tunnel_w1_ip4();
+        *tp++=0x00000000 | ((tunnel_w1_ip4)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w2_ip4 */
+        tunnel_w2_ip4 = EVAL_tunnel_w2_ip4();
+        *tp++=0x00000000 | ((tunnel_w2_ip4)&0xffffffffu)<<0;
+        tunnel_ip_addr = EVAL_tunnel_ip_addr();
+        TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+        tp += 2;
+        break;
+    case 7: /* ipv6_out_tunnel */
+        /* INS OUT,ORIG_TOKEN,40 */
+        *tp++=0x21d80000 | ((40u)&0x1ffffu)<<0;
+        /* DATA32 tunnel_w0_ip6 */
+        tunnel_w0_ip6 = EVAL_tunnel_w0_ip6();
+        *tp++=0x00000000 | ((tunnel_w0_ip6)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w1_ip6 */
+        tunnel_w1_ip6 = EVAL_tunnel_w1_ip6();
+        *tp++=0x00000000 | ((tunnel_w1_ip6)&0xffffffffu)<<0;
+        tunnel_ip_addr = EVAL_tunnel_ip_addr();
+        TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+        tp += 8;
+        break;
+    case 6: /* ipv4_in_transp */
+        /* IPV4CHK OUT,0,0 */
+        *tp++=0x61000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+        /* DIR OUT,hdrlen-12 */
+        *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+        break;
+    case 3: /* ipv4_in_transp_nohdrproc */
+        /* DIR OUT, hdrlen */
+        *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+        break;
+    case 12: /* ipv6_in_transp */
+        nh = EVAL_nh();
+        if (nh == 50u)
+        {
+            /* IPV6 OUT,00,00                      ; zeroise the NH and payload length */
+            *tp++=0x81000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+            /* DIR OUT,hdrlen-8                    ; pass the remaining header words */
+            *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* IPV6 OUT,nh,00                      ; bypass NH, but zeroise the payload length */
+            *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+            /* DIR OUT,prev_nhoffset-8   ; pass the remaining data until the next header of the last extentnio header */
+            prev_nhoffset = EVAL_prev_nhoffset();
+            *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+            /* REPL OUT,ORIG_TOKEN,1               ; zeroize the NH field */
+            *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+            /* DATA32 00                           ; */
+            *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+            /* DIR OUT,hdrlen-prev_nhoffset-1      ; bypass the rest of the last extension header */
+            *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+        }
+        break;
+    case 4: /* ipv4_in_tunnel */
+    case 8: /* ipv6_in_tunnel */
+    case 24: /* ipv4_in_tunnel_natt */
+    case 28: /* ipv6_in_tunnel_natt */
+        /* DIR OUT, ohdrlen     ; keep (optionally) outer IP heade */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0x01000000 | ((ohdrlen)&0x1ffffu)<<0;
+        /* REM hdrlen-ohdrlen   ; remobe IP header (optionally) and NATT header. */
+        *tp++=0x40d80000 | ((hdrlen-ohdrlen)&0x1ffffu)<<0;
+        break;
+    case 25: /* ipv4_out_transp_natt */
+        /* IPV4CHK OUT,17,outlen    ; include 8 byte of NAT-T */
+        outlen = EVAL_outlen();
+        *tp++=0x61000000 | ((17u)&0xffu)<<16 | ((outlen)&0xffffu)<<0;
+        is_nat = EVAL_is_nat();
+        if (is_nat != 0u)
+        {
+            /* REPL OUT,ORIG_TOKEN,8 */
+            *tp++=0x31d80000 | ((8u)&0x1ffffu)<<0;
+            tunnel_ip_addr = EVAL_tunnel_ip_addr();
+            TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+            tp += 2;
+            /* DIR OUT,hdrlen-20 */
+            *tp++=0x01000000 | ((-20u+hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR OUT,hdrlen-12 */
+            *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+        }
+        /* INS OUT,ORIG_TOKEN,8 */
+        *tp++=0x21d80000 | ((8u)&0x1ffffu)<<0;
+        /* DATA32 ports_natt */
+        ports_natt = EVAL_ports_natt();
+        *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+        /* SWAP16 outlen - hdrlen ; include 8 byte of NAT-T */
+        *tp++ = ByteSwap16(outlen-hdrlen);
+        break;
+    case 31: /* ipv6_out_transp_natt */
+        if (hdrlen > 40u)
+        {
+            /* IPV6 OUT,nh,outlen-40              ; include 8 bytes of NAT-T */
+            nh = EVAL_nh();
+            outlen = EVAL_outlen();
+            *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((-40u+outlen)&0xffffu)<<0;
+            is_nat = EVAL_is_nat();
+            if (is_nat != 0u)
+            {
+                /* REPL OUT,ORIG_TOKEN,32 */
+                *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+                tunnel_ip_addr = EVAL_tunnel_ip_addr();
+                TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+                tp += 8;
+                /* DIR OUT,prev_nhoffset-40 */
+                prev_nhoffset = EVAL_prev_nhoffset();
+                *tp++=0x01000000 | ((-40u+prev_nhoffset)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR OUT,prev_nhoffset-8    ; -8 to include two 32-bit words of the IPv6 header passed via IPV6 instruction */
+                prev_nhoffset = EVAL_prev_nhoffset();
+                *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+            }
+            /* REPL OUT,ORIG_TOKEN,1                ; replace NH byte of the last extension header with UDP type */
+            *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+            /* DATA32 17                            ; */
+            *tp++=0x00000000 | ((17u)&0xffffffffu)<<0;
+            /* DIR OUT,hdrlen-prev_nhoffset-1    ; bypass the rest data of the last extension header */
+            prev_nhoffset = EVAL_prev_nhoffset();
+            *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* IPV6 OUT,17,outlen-hdrlen         ; include 8 bytes of NAT-T */
+            outlen = EVAL_outlen();
+            *tp++=0x81000000 | ((17u)&0xffu)<<16 | ((outlen-hdrlen)&0xffffu)<<0;
+            is_nat = EVAL_is_nat();
+            if (is_nat != 0u)
+            {
+                /* REPL OUT,ORIG_TOKEN,32 */
+                *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+                tunnel_ip_addr = EVAL_tunnel_ip_addr();
+                TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+                tp += 8;
+                /* DIR OUT,hdrlen-40 */
+                *tp++=0x01000000 | ((-40u+hdrlen)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR OUT,hdrlen-8 */
+                *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+            }
+        }
+        /* INS OUT,ORIG_TOKEN,8 */
+        *tp++=0x21d80000 | ((8u)&0x1ffffu)<<0;
+        /* DATA32 ports_natt */
+        ports_natt = EVAL_ports_natt();
+        *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+        outlen = EVAL_outlen();
+        /* SWAP16 outlen-hdrlen                  ; include 8 bytes of NAT-T */
+        *tp++ = ByteSwap16(outlen-hdrlen);
+        break;
+    case 22: /* ipv4_out_tunnel_natt */
+        /* INS OUT,ORIG_TOKEN,28 */
+        *tp++=0x21d80000 | ((28u)&0x1ffffu)<<0;
+        /* DATA32 tunnel_w0_ip4 */
+        tunnel_w0_ip4 = EVAL_tunnel_w0_ip4();
+        *tp++=0x00000000 | ((tunnel_w0_ip4)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w1_ip4 */
+        tunnel_w1_ip4 = EVAL_tunnel_w1_ip4();
+        *tp++=0x00000000 | ((tunnel_w1_ip4)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w2_ip4 */
+        tunnel_w2_ip4 = EVAL_tunnel_w2_ip4();
+        *tp++=0x00000000 | ((tunnel_w2_ip4)&0xffffffffu)<<0;
+        tunnel_ip_addr = EVAL_tunnel_ip_addr();
+        TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+        tp += 2;
+        /* DATA32 ports_natt */
+        ports_natt = EVAL_ports_natt();
+        *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+        outlen = EVAL_outlen();
+        ohdrlen = EVAL_ohdrlen();
+        /* SWAP16 outlen+8 - ohdrlen                ; include 8 byte of NAT-T */
+        *tp++ = ByteSwap16(8u+outlen-ohdrlen);
+        break;
+    case 27: /* ipv6_out_tunnel_natt */
+        /* INS OUT,ORIG_TOKEN,48 */
+        *tp++=0x21d80000 | ((48u)&0x1ffffu)<<0;
+        /* DATA32 tunnel_w0_ip6 */
+        tunnel_w0_ip6 = EVAL_tunnel_w0_ip6();
+        *tp++=0x00000000 | ((tunnel_w0_ip6)&0xffffffffu)<<0;
+        /* DATA32 tunnel_w1_ip6 */
+        tunnel_w1_ip6 = EVAL_tunnel_w1_ip6();
+        *tp++=0x00000000 | ((tunnel_w1_ip6)&0xffffffffu)<<0;
+        tunnel_ip_addr = EVAL_tunnel_ip_addr();
+        TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+        tp += 8;
+        /* DATA32 ports_natt */
+        ports_natt = EVAL_ports_natt();
+        *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+        outlen = EVAL_outlen();
+        ohdrlen = EVAL_ohdrlen();
+        /* SWAP16 outlen+8 - ohdrlen                ; include 8 byte of NAT-T */
+        *tp++ = ByteSwap16(8u+outlen-ohdrlen);
+        break;
+    case 26: /* ipv4_in_transp_natt */
+        /* IPV4CHK OUT,0,0                         ; IP header update instruction */
+        *tp++=0x61000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+        is_nat = EVAL_is_nat();
+        if (is_nat != 0u)
+        {
+            /* REPL OUT,ORIG_TOKEN,4 */
+            *tp++=0x31d80000 | ((4u)&0x1ffffu)<<0;
+            tunnel_ip_addr = EVAL_tunnel_ip_addr();
+            TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 4);
+            tp += 1;
+            /* REPL OUT,ORIG_TOKEN,4 */
+            *tp++=0x31d80000 | ((4u)&0x1ffffu)<<0;
+            dst_ip_addr = EVAL_dst_ip_addr();
+            TokenBuilder_CopyBytes(tp, dst_ip_addr, 4);
+            tp += 1;
+            /* DIR OUT,hdrlen-20-8 */
+            *tp++=0x01000000 | ((-28u+hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR OUT,hdrlen-12-8                     ; bypass the rest of IP header words */
+            *tp++=0x01000000 | ((-20u+hdrlen)&0x1ffffu)<<0;
+        }
+        /* REM 8                                   ; remove NAT-T UDP header */
+        *tp++=0x40d80000 | ((8u)&0x1ffffu)<<0;
+        break;
+    case 32: /* ipv6_in_transp_natt */
+        nh = EVAL_nh();
+        if (nh == 17u)
+        {
+            /* IPV6 OUT,00,00                      ; bypass IPv6 header and zeroise length and protocol fields */
+            *tp++=0x81000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+            is_nat = EVAL_is_nat();
+            if (is_nat != 0u)
+            {
+                /* REPL OUT,ORIG_TOKEN,32 */
+                *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+                tunnel_ip_addr = EVAL_tunnel_ip_addr();
+                TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+                tp += 8;
+                /* DIR OUT,hdrlen-40-8 */
+                *tp++=0x01000000 | ((-48u+hdrlen)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR OUT,hdrlen-8-8                  ; bypass rest of the IPv6 header (hdrlen includes the UDP length) */
+                *tp++=0x01000000 | ((-16u+hdrlen)&0x1ffffu)<<0;
+            }
+        }
+        else
+        {
+            prev_nhoffset = EVAL_prev_nhoffset();
+            /* IPV6 OUT,nh,00                      ; bypass IPv6 header and restore the next header */
+            *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+            is_nat = EVAL_is_nat();
+            if (is_nat != 0u)
+            {
+                /* REPL OUT,ORIG_TOKEN,32 */
+                *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+                tunnel_ip_addr = EVAL_tunnel_ip_addr();
+                TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+                tp += 8;
+                /* DIR OUT,prev_nhoffset-40 */
+                *tp++=0x01000000 | ((-40u+prev_nhoffset)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR OUT,prev_nhoffset-8   ; bypass rest of the IPv6 header (hdrlen includes the UDP length) */
+                *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+            }
+            /* REPL OUT,ORIG_TOKEN,1               ; zeroise the NH byte of the last extension header */
+            *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+            /* DATA32 00                           ; */
+            *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+            /* DIR OUT,hdrlen-prev_nhoffset-1-8    ; bypass the rest data of the last extension header */
+            *tp++=0x01000000 | ((-9u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+        }
+        /* REM 8                                   ; remove UDP NAT-T header */
+        *tp++=0x40d80000 | ((8u)&0x1ffffu)<<0;
+        break;
+    case 13: /* ipv4_out_dtls */
+        /* IPV4CHK OUT,nh,outlen+hdrlen */
+        nh = EVAL_nh();
+        outlen = EVAL_outlen();
+        *tp++=0x61000000 | ((nh)&0xffu)<<16 | ((outlen+hdrlen)&0xffffu)<<0;
+        if (nh == 136u)
+        {
+            /* DIR OUT,hdrlen-12 */
+            *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR OUT, hdrlen-16 */
+            *tp++=0x01000000 | ((-16u+hdrlen)&0x1ffffu)<<0;
+            /* REPL OUT,ORIG_TOKEN,2 */
+            *tp++=0x31d80000 | ((2u)&0x1ffffu)<<0;
+            /* SWAP16 outlen+8 ; include 8 bytes UDP header */
+            *tp++ = ByteSwap16(8u+outlen);
+            /* DIR OUT,2 */
+            *tp++=0x01000000 | ((2u)&0x1ffffu)<<0;
+        }
+        break;
+    case 33: /* ipv6_out_dtls */
+        /* IPV6 OUT,prev_nhoffset,outlen+hdrlen-40 */
+        prev_nhoffset = EVAL_prev_nhoffset();
+        outlen = EVAL_outlen();
+        *tp++=0x81000000 | ((prev_nhoffset)&0xffu)<<16 | ((-40u+outlen+hdrlen)&0xffffu)<<0;
+        nh = EVAL_nh();
+        if (nh == 136u)
+        {
+            /* DIR OUT,hdrlen-8 */
+            *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR OUT, hdrlen-12 */
+            *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+            /* REPL OUT,ORIG_TOKEN,2 */
+            *tp++=0x31d80000 | ((2u)&0x1ffffu)<<0;
+            /* SWAP16 outlen+8 ; include 8 bytes UDP header */
+            *tp++ = ByteSwap16(8u+outlen);
+            /* DIR OUT,2 */
+            *tp++=0x01000000 | ((2u)&0x1ffffu)<<0;
+        }
+        break;
+    }
+#endif
+#endif
+    switch(proto)
+    {
+    case 0: /* esp_out */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (packetsize <= bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (ivhandling == 2u)
+        {
+            /* INS      HASH,ORIG_SPI,8 */
+            *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+            /* INS      HASH,ORIG_IV1,ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x23a80000 | ((ivlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS      HASH,ORIG_SPI,8+ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x23900000 | ((8u+ivlen)&0x1ffffu)<<0;
+        }
+        /* DIR      CRYPTHASH,packetsize-bypass-hdrlen */
+        *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq == 0u)
+            {
+                /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+                nextheader = EVAL_nextheader();
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            }
+            else
+            {
+                /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST */
+                nextheader = EVAL_nextheader();
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2f200000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+                /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2,4,LASTHASH */
+                *tp++=0x224a0000 | ((4u)&0x1ffffu)<<0;
+            }
+            /* INS      OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS      CRYPT,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASHPKT */
+            nextheader = EVAL_nextheader();
+            pad_bytes = EVAL_pad_bytes();
+            *tp++=0x2d260000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+        }
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX      ORIG_SEQNUM,seq_offset,1+extseq */
+        seq_offset = EVAL_seq_offset();
+        extseq = EVAL_extseq();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 1: /* esp_in */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        pad_blocksize = EVAL_pad_blocksize();
+        if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        pad_remainder = EVAL_pad_remainder();
+        if (pad_remainder != 0u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+#if TKB_HAVE_ECN_FIXUP == 1u
+        /* DATA32 ecn_fixup_instr */
+        ecn_fixup_instr = EVAL_ecn_fixup_instr();
+        *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+        if (ivhandling == 0u)
+        {
+            /* RETR     HASHONLY,ORIG_SPI,8 */
+            *tp++=0x42900000 | ((8u)&0x1ffffu)<<0;
+            /* RETR     HASHONLY,ORIG_IV1,ivlen */
+            *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* RETR     HASHONLY,ORIG_SPI,8+ivlen */
+            *tp++=0x42900000 | ((8u+ivlen)&0x1ffffu)<<0;
+        }
+        if (icvlen > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq != 1u)
+            {
+                /* DIR   CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+                *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR   CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST */
+                *tp++=0x0f000000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+                /* INS   HASHONLY, ORIG_EXTSEQNUM_RES2,4,LASTHASH */
+                *tp++=0x224a0000 | ((4u)&0x1ffffu)<<0;
+            }
+            /* RETR  NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+            *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR CRYPT,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASHPKT */
+            *tp++=0x0d060000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 2: /* esp_out_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (packetsize <= bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound CCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS      HASHONLY,ORIG_TOKEN,4 */
+        *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+        /* DATA32   salt */
+        salt = EVAL_salt();
+        *tp++=0x00000000 | ((salt)&0xffffffffu)<<0;
+        /* INS      HASHONLY,ORIG_IV1,8 */
+        *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+        /* INS      HASHONLY,ORIG_TOKEN,6     ; Insert message length + AAD length. */
+        *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+        /* DATA32 swaplen                     ; Message length, byte-swapped */
+        swaplen = EVAL_swaplen();
+        *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* DATA32   0x0800  ; AAD length, byte-swapped */
+            *tp++=0x00000000 | ((2048u)&0xffffffffu)<<0;
+            /* INS      HASH,ORIG_SPI,8 */
+            *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, PAD_ZERO, 0, 6 */
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((6u)&0xffffu)<<0;
+        }
+        else
+        {
+            /* DATA32   0x0c00 ; AAD length, byte-swapped */
+            *tp++=0x00000000 | ((3072u)&0xffffffffu)<<0;
+            /* INS      HASH,ORIG_SPI,4 */
+            *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASH,ORIG_SEQNUM_RES, 4 */
+            *tp++=0x23980000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, PAD_ZERO, 0, 2 */
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((2u)&0xffffu)<<0;
+        }
+        /* INS      OUT,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* REMRES   bypass+ohdrlen+8+ivlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      CRYPTHASH, packetsize-bypass-hdrlen */
+        *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        hashpad = EVAL_hashpad();
+        if (hashpad == 0u)
+        {
+            /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+            nextheader = EVAL_nextheader();
+            pad_bytes = EVAL_pad_bytes();
+            *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+        }
+        else
+        {
+            /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST */
+            nextheader = EVAL_nextheader();
+            pad_bytes = EVAL_pad_bytes();
+            *tp++=0x2f200000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            /* INS      HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+            *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+        }
+        /* INS      OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX      ORIG_SEQNUM,seq_offset,1+extseq */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 3: /* esp_in_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        pad_blocksize = EVAL_pad_blocksize();
+        if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound CCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        pad_remainder = EVAL_pad_remainder();
+        if (pad_remainder != 0u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound CCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* RETR     NONE,ORIG_SPI,8 */
+        *tp++=0x40900000 | ((8u)&0x1ffffu)<<0;
+        /* RETR     NONE,ORIG_IV1,ivlen */
+        *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* INS      HASHONLY,ORIG_TOKEN,4 */
+        *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+        /* DATA32   salt */
+        salt = EVAL_salt();
+        *tp++=0x00000000 | ((salt)&0xffffffffu)<<0;
+        /* INS      HASHONLY,ORIG_IV1,8 */
+        *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+        /* INS      HASHONLY,ORIG_TOKEN,6    ; Insert message length + AAD length. */
+        *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+        /* DATA32 swaplen                    ; Message length, byte-swapped */
+        swaplen = EVAL_swaplen();
+        *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            /* DATA32 0x0800  ; AAD length, byte-swapped */
+            *tp++=0x00000000 | ((2048u)&0xffffffffu)<<0;
+            /* INS      HASHONLY,ORIG_SPI,8 */
+            *tp++=0x22900000 | ((8u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, PAD_ZERO, 0, 6 */
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((6u)&0xffffu)<<0;
+        }
+        else
+        {
+            /* DATA32 0x0c00 ; AAD length, byte-swapped */
+            *tp++=0x00000000 | ((3072u)&0xffffffffu)<<0;
+            /* INS      HASHONLY,ORIG_SPI,4 */
+            *tp++=0x22900000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_SEQNUM_RES, 4 */
+            *tp++=0x22980000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, PAD_ZERO, 0, 2 */
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((2u)&0xffffu)<<0;
+        }
+        /* REMRES   bypass+ohdrlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        /* DATA32 ecn_fixup_instr */
+        ecn_fixup_instr = EVAL_ecn_fixup_instr();
+        *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        hashpad = EVAL_hashpad();
+        if (hashpad == 0u)
+        {
+            /* DIR      CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+            *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR      CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST */
+            *tp++=0x0f000000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+            /* INS      HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+            *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+        }
+        /* RETR     NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 4: /* esp_out_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (packetsize <= bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* INS      HASH,ORIG_SPI,8,LAST */
+            *tp++=0x2b900000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS      HASH,ORIG_SPI,4 */
+            *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASH,ORIG_SEQNUM_RES, 4, LAST */
+            *tp++=0x2b980000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS      OUT,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* REMRES   bypass+ohdrlen+8+ivlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      CRYPTHASH, packetsize-bypass-hdrlen */
+        *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+        nextheader = EVAL_nextheader();
+        pad_bytes = EVAL_pad_bytes();
+        *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+        /* INS      OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX      ORIG_SEQNUM,seq_offset,1+extseq */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 5: /* esp_in_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        pad_blocksize = EVAL_pad_blocksize();
+        if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        pad_remainder = EVAL_pad_remainder();
+        if (pad_remainder != 0u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            /* RETR     HASHONLY,ORIG_SPI,8,LAST */
+            *tp++=0x4a900000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* RETR     HASHONLY,ORIG_SPI,4 */
+            *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+            /* RETR     NONE,ORIG_SEQNUM_RES,4 */
+            *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_SEQNUM_RES,4,LAST */
+            *tp++=0x2a980000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* RETR     NONE,ORIG_IV1,ivlen */
+        *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* REMRES   bypass+ohdrlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        /* DATA32 ecn_fixup_instr */
+        ecn_fixup_instr = EVAL_ecn_fixup_instr();
+        *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+        /* RETR     NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 6: /* esp_out_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (packetsize <= bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound GMAC\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* INS      HASH,ORIG_SPI,8 */
+            *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS      HASH,ORIG_SPI,4 */
+            *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASH,ORIG_SEQNUM_RES, 4 */
+            *tp++=0x23980000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS      HASH,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x23a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* REMRES   bypass+ohdrlen+8+ivlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      HASH, packetsize-bypass-hdrlen */
+        *tp++=0x03000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        /* INS      HASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+        nextheader = EVAL_nextheader();
+        pad_bytes = EVAL_pad_bytes();
+        *tp++=0x2b220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+        /* INS      OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX      ORIG_SEQNUM,seq_offset,1+extseq */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 7: /* esp_in_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        pad_blocksize = EVAL_pad_blocksize();
+        if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound GMAC\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        pad_remainder = EVAL_pad_remainder();
+        if (pad_remainder != 0u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound GMAC\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            /* RETR     HASHONLY,ORIG_SPI,8 */
+            *tp++=0x42900000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* RETR     HASHONLY,ORIG_SPI,4 */
+            *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+            /* RETR     NONE,ORIG_SEQNUM_RES,4 */
+            *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_SEQNUM_RES,4 */
+            *tp++=0x22980000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* RETR     HASHONLY,ORIG_IV1,ivlen */
+        *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* REMRES   bypass+ohdrlen, 16 */
+        ohdrlen = EVAL_ohdrlen();
+        *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+        /* DATA32 ecn_fixup_instr */
+        ecn_fixup_instr = EVAL_ecn_fixup_instr();
+        *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      HASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+        *tp++=0x0b020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+        /* RETR     NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 8: /* ssltls_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            /* INS OUT,ORIG_TOKEN,4 */
+            *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 0x0000001  ; Insert DTLS/CAPWAP header. */
+            *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+        *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_SEQNUM,4 */
+        *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+        nextheader = EVAL_nextheader();
+        *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        antireplay = EVAL_antireplay();
+        if (antireplay != 0u)
+        {
+            /* INS HASH,ORIG_SPI,2          ; For TLS/DTLS, hash version field. */
+            *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS OUT,ORIG_SPI,2           ; For SSL, do not hash version field. */
+            *tp++=0x21900000 | ((2u)&0x1ffffu)<<0;
+        }
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            /* INS OUT,ORIG_EXTSEQNUM,4 */
+            *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+            /* INS OUT,ORIG_SEQNUM,4 */
+            *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,2 */
+        *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swaplen                   ; Payload length to hash. */
+        swaplen = EVAL_swaplen();
+        *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        /* INS OUT,ORIG_TOKEN,2 */
+        *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen              ; Fragment length to output. */
+        swap_fraglen = EVAL_swap_fraglen();
+        *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+        /* INS OUT,ORIG_IV0,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a00000 | ((ivlen)&0x1ffffu)<<0;
+        if (packetsize != bypass+hdrlen)
+        {
+            /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LASTHASH */
+            *tp++=0x07020000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_ZERO, 0, 0, LASTHASH */
+            *tp++=0x27020000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            /* INS CRYPT,ORIG_HASH,icvlen,LAST,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x2de60000 | ((icvlen)&0x1ffffu)<<0;
+            /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+            *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,2 */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            break;
+        case 1: /* upd_arc4 */
+            /* INS CRYPT,ORIG_HASH,icvlen,LAST,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x2de60000 | ((icvlen)&0x1ffffu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,2 */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            /* CTX ORIG_CHKSUM,iv_offset,1,P ; Update IJ pointer */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0ce1800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            /* CTX ORIG_CHKSUM_STORE,0,1,P   ; Update ARC4 state. */
+            *tp++=0xe0d61800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            break;
+        case 2: /* upd_iv2 */
+            /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+            if (antireplay != 0u)
+            {
+                /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            }
+            else
+            {
+                /* INS CRYPT,PAD_SSL,0,pad_bytes,LAST,LASTHASHPKT */
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2d360000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            }
+            /* CTX ORIG_SEQNUM,seq_offset,2 */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            /* CTX ORIG_IV0,iv_offset,2,P */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            break;
+        case 3: /* upd_iv4 */
+            /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+            if (antireplay != 0u)
+            {
+                /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            }
+            else
+            {
+                /* INS CRYPT,PAD_SSL,0,pad_bytes,LAST,LASTHASHPKT */
+                pad_bytes = EVAL_pad_bytes();
+                *tp++=0x2d360000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            }
+            /* CTX ORIG_SEQNUM,seq_offset,2 */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            /* CTX ORIG_IV0,iv_offset,4,P */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+            break;
+        case 4: /* upd_blk */
+            /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+            /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+            pad_bytes = EVAL_pad_bytes();
+            *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+            /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+            *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,2 */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            break;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 9: /* ssltls_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        paylen = EVAL_paylen();
+        if (paylen == 4294967295u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, payload size for SSLTLS inbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        upd_handling = EVAL_upd_handling();
+        if (upd_handling <= 1u)
+        {
+            if (bypass > 0u)
+            {
+                /* DIR OUT,bypass */
+                *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+            }
+            if (hdrlen > 0u)
+            {
+                /* DIR OUT,hdrlen */
+                *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+            }
+            capwap_in = EVAL_capwap_in();
+            if (capwap_in != 0u)
+            {
+                /* REM 4  ; Remove DTLS/CAPWAP header. */
+                *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+            }
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                ohdrlen = EVAL_ohdrlen();
+                if (ohdrlen > hdrlen)
+                {
+                    /* RETR OUT,ORIG_SPI,3    ; Extract Type and Version. */
+                    *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                    *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+                    *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+                    *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+                    /* INS HASH,ORIG_TOKEN,2 */
+                    *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+                    /* DATA32 swaplen */
+                    swaplen = EVAL_swaplen();
+                    *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+                    if (ohdrlen-hdrlen > 5u)
+                    {
+                        /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+                        *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+                    }
+                }
+                else
+                {
+                    /* RETR NONE,ORIG_SPI,3    ; Extract Type and Version. */
+                    *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                    *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+                    *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+                    *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_TOKEN,2 */
+                    *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+                    /* DATA32 swaplen */
+                    swaplen = EVAL_swaplen();
+                    *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+                }
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_EXTSEQNUM,4  ; Extract from SA. */
+                *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_SEQNUM,4 */
+                *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    /* DIR HASHONLY,3       ; Hash type and version number */
+                    *tp++=0x02000000 | ((3u)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* DIR HASHONLY,1       ; Hash type only for SSL */
+                    *tp++=0x02000000 | ((1u)&0x1ffffu)<<0;
+                    /* REM 2 */
+                    *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+                }
+                /* INS HASHONLY,ORIG_TOKEN,2 */
+                *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+                /* DATA32 swaplen */
+                swaplen = EVAL_swaplen();
+                *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+            }
+            /* REM 2                              ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            /* REMRES bypass+ohdrlen+paylen,icvlen          ; Cause the MAC to be removed */
+            ohdrlen = EVAL_ohdrlen();
+            icvlen = EVAL_icvlen();
+            *tp++=0xa0000000 | ((bypass+ohdrlen+paylen)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+            /* DIR CRYPTHASH,paylen,LASTHASH */
+            *tp++=0x07020000 | ((paylen)&0x1ffffu)<<0;
+            switch(upd_handling)
+            {
+            case 0: /* upd_null */
+                /* DIR CRYPT,icvlen,LAST,LASTHASHPKT */
+                *tp++=0x0d060000 | ((icvlen)&0x1ffffu)<<0;
+                if (extseq == 0u)
+                {
+                    /* VERIFY icvlen,H */
+                    *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+                    /* CTX ORIG_SEQNUM,seq_offset,2,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                }
+                else if (extseq == 1u)
+                {
+                    /* VERIFY icvlen,H */
+                    *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+                }
+                else
+                {
+                    /* VERIFY icvlen,S,H */
+                    *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+                    /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+                }
+                break;
+            case 1: /* upd_arc4 */
+                /* DIR CRYPT,icvlen,LAST,LASTHASHPKT */
+                *tp++=0x0d060000 | ((icvlen)&0x1ffffu)<<0;
+                /* VERIFY icvlen,H */
+                *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+                /* CTX ORIG_SEQNUM,seq_offset,2,P */
+                seq_offset = EVAL_seq_offset();
+                *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                /* CTX ORIG_CHKSUM,iv_offset,1,P ; Update IJ pointer */
+                iv_offset = EVAL_iv_offset();
+                *tp++=0xe0ce1800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+                /* CTX ORIG_CHKSUM_STORE,0,1,P   ; Update ARC4 state. */
+                *tp++=0xe0d61800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+                break;
+            }
+        }
+        else
+        {
+            /* REMRES 0,4,NOUPDCHK */
+            *tp++=0xa0020000 | ((0u)&0xffffu)<<0 | ((4u)&0x3fu)<<19;
+            cipher_is_aes = EVAL_cipher_is_aes();
+            if (cipher_is_aes == 0u)
+            {
+                /* INS CRYPTONLY,ORIG_TOKEN,12 */
+                *tp++=0x24d80000 | ((12u)&0x1ffffu)<<0;
+                ssltls_lastblock = EVAL_ssltls_lastblock();
+                TokenBuilder_CopyBytes(tp, ssltls_lastblock, 12);
+                tp += 3;
+                /* INS CRYPT,ORIG_TOKEN,4 */
+                *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+                ssltls_lastword = EVAL_ssltls_lastword();
+                TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+                tp += 1;
+            }
+            else
+            {
+                /* INS CRYPTONLY,ORIG_TOKEN,28 */
+                *tp++=0x24d80000 | ((28u)&0x1ffffu)<<0;
+                ssltls_lastblock = EVAL_ssltls_lastblock();
+                TokenBuilder_CopyBytes(tp, ssltls_lastblock, 28);
+                tp += 7;
+                /* INS CRYPT,ORIG_TOKEN,4 */
+                *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+                ssltls_lastword = EVAL_ssltls_lastword();
+                TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+                tp += 1;
+            }
+            /* DIR NONE,0,LAST */
+            *tp++=0x08000000 | ((0u)&0x1ffffu)<<0;
+            if (bypass+hdrlen > 0u)
+            {
+                /* DIR OUT,bypass+hdrlen */
+                *tp++=0x01000000 | ((bypass+hdrlen)&0x1ffffu)<<0;
+            }
+            capwap_in = EVAL_capwap_in();
+            if (capwap_in != 0u)
+            {
+                /* REM 4  ; Remove DTLS/CAPWAP header. */
+                *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+            }
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                ohdrlen = EVAL_ohdrlen();
+                if (ohdrlen > hdrlen)
+                {
+                    /* RETR OUT,ORIG_SPI,3    ; Extract Type and Version. */
+                    *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                    *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+                    *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+                    *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+                    /* INS HASH,ORIG_LENCOR,paylen-1 */
+                    *tp++=0x23780000 | ((-1u+paylen)&0x1ffffu)<<0;
+                    if (ohdrlen-hdrlen > 5u)
+                    {
+                        /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+                        *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+                    }
+                }
+                else
+                {
+                    /* RETR NONE,ORIG_SPI,3    ; Extract Type and Version. */
+                    *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                    *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+                    /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+                    *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+                    *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+                    /* INS HASHONLY,ORIG_LENCOR,paylen-1 */
+                    *tp++=0x22780000 | ((-1u+paylen)&0x1ffffu)<<0;
+                }
+            }
+            else
+            {
+                /* RETR NONE,ORIG_SPI,3    ; Extract Type and Version. */
+                *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_EXTSEQNUM,4  ; Extract from SA. */
+                *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_SEQNUM,4 */
+                *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    /* INS HASHONLY,ORIG_SPI_RES,3       ; Hash type and version number */
+                    *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* INS HASHONLY,ORIG_SPI_RES,1       ; Hash type only. */
+                    *tp++=0x22c00000 | ((1u)&0x1ffffu)<<0;
+                }
+                /* INS HASHONLY,ORIG_LENCOR,paylen-1 */
+                *tp++=0x22780000 | ((-1u+paylen)&0x1ffffu)<<0;
+            }
+            /* REM 2                              ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            ivlen = EVAL_ivlen();
+            if (ivlen > 0u)
+            {
+                /* RETR NONE,ORIG_IV0,ivlen */
+                *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+            }
+            /* REMRES bypass+ohdrlen,icvlen,NOUPDCHK          ; Cause the MAC to be removed */
+            ohdrlen = EVAL_ohdrlen();
+            icvlen = EVAL_icvlen();
+            *tp++=0xa0020000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+            /* DIRX CRYPTHASH,ORIG_LENCOR,0,LASTHASH */
+            *tp++=0x077a0000 | ((0u)&0x1ffffu)<<0;
+            /* DIRX CRYPT,ORIG_LENCOR,icvlen+1,LAST,LASTHASHPKT */
+            *tp++=0x0d7e0000 | ((1u+icvlen)&0x1ffffu)<<0;
+            switch(upd_handling)
+            {
+            case 2: /* upd_iv2 */
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    /* VERIFY icvlen,P,H */
+                    *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+                }
+                else
+                {
+                    /* VERIFY icvlen,H */
+                    *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+                }
+                /* CTX ORIG_SEQNUM,seq_offset,2,P */
+                seq_offset = EVAL_seq_offset();
+                *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                /* CTX ORIG_IV0,iv_offset,2,P */
+                iv_offset = EVAL_iv_offset();
+                *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                break;
+            case 3: /* upd_iv4 */
+                antireplay = EVAL_antireplay();
+                if (antireplay != 0u)
+                {
+                    /* VERIFY icvlen,P,H */
+                    *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+                }
+                else
+                {
+                    /* VERIFY icvlen,H */
+                    *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+                }
+                /* CTX ORIG_SEQNUM,seq_offset,2,P */
+                seq_offset = EVAL_seq_offset();
+                *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                /* CTX ORIG_IV0,iv_offset,4,P */
+                iv_offset = EVAL_iv_offset();
+                *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+                break;
+            case 4: /* upd_blk */
+                if (extseq == 0u)
+                {
+                    /* VERIFY icvlen,P,H */
+                    *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+                    /* CTX ORIG_SEQNUM,seq_offset,2,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+                }
+                else if (extseq == 1u)
+                {
+                    /* VERIFY icvlen,P,H */
+                    *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+                }
+                else
+                {
+                    /* VERIFY icvlen,P,S,H */
+                    *tp++=0xd9070000 | ((icvlen)&0x7fu)<<0;
+                    /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+                }
+                break;
+            }
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 21: /* ssltls_gcm_out */
+    case 37: /* ssltls_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM or ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            /* INS OUT,ORIG_TOKEN,4 */
+            *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 0x0000001  ; Insert DTLS/CAPWAP header. */
+            *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+        *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_SEQNUM,4 */
+        *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+        nextheader = EVAL_nextheader();
+        *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASH,ORIG_SPI,2          ; For TLS/DTLS, hash version field. */
+        *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            /* INS OUT,ORIG_EXTSEQNUM,4 ; Output sequence number for DTLS */
+            *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+            /* INS OUT,ORIG_SEQNUM,4 */
+            *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,2,LAST */
+        *tp++=0x2ad80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swaplen                   ; Payload length to hash. */
+        swaplen = EVAL_swaplen();
+        *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        /* INS OUT,ORIG_TOKEN,2 */
+        *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen              ; Fragment length to output. */
+        swap_fraglen = EVAL_swap_fraglen();
+        *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+        /* INS OUT,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+        if (proto != 37u)
+        {
+            if (extseq != 0u)
+            {
+                /* REMRES bypass + hdrlen + capwap_out + 5 + 8 + 8, 16 */
+                *tp++=0xa0000000 | ((21u+bypass+hdrlen+capwap_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            }
+            else
+            {
+                /* REMRES bypass + hdrlen + 5 + 8, 16 */
+                *tp++=0xa0000000 | ((13u+bypass+hdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            }
+            /* INS CRYPT, PAD_ZERO, 0, 16 */
+            *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        }
+        if (packetsize != bypass+hdrlen)
+        {
+            /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LAST,LASTHASH */
+            *tp++=0x0f020000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_ZERO, 0, 0, LAST, LASTHASH */
+            *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2 */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 22: /* ssltls_gcm_in */
+    case 38: /* ssltls_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        paylen = EVAL_paylen();
+        if (paylen == 4294967295u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM or ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (hdrlen > 0u)
+        {
+            /* DIR OUT,hdrlen */
+            *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+        }
+        capwap_in = EVAL_capwap_in();
+        if (capwap_in != 0u)
+        {
+            /* REM 4  ; Remove DTLS/CAPWAP header. */
+            *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+        }
+        ohdrlen = EVAL_ohdrlen();
+        if (ohdrlen > hdrlen)
+        {
+            /* RETR OUT,ORIG_SPI,3    ; Extract Type and Version. */
+            *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+            /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+            *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+            /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+            *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+            /* REM 2                    ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            /* RETR NONE,ORIG_IV1,ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+            *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+            /* INS HASH,ORIG_TOKEN,2,LAST */
+            *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+            /* DATA32 swaplen */
+            swaplen = EVAL_swaplen();
+            *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+            if (ohdrlen-hdrlen > 5u)
+            {
+                /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+                *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+            }
+        }
+        else
+        {
+            /* RETR NONE,ORIG_SPI,3    ; Extract Type and Version. */
+            *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+                /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+                *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_EXTSEQNUM,4  ; Extract from SA. */
+                *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_SEQNUM,4 */
+                *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+            }
+            /* REM 2                    ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            /* RETR NONE,ORIG_IV1,ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+            *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_TOKEN,2,LAST */
+            *tp++=0x2ad80000 | ((2u)&0x1ffffu)<<0;
+            /* DATA32 swaplen */
+            swaplen = EVAL_swaplen();
+            *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        }
+        if (proto != 38u)
+        {
+            /* REMRES bypass+ohdrlen, 16 */
+            *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            /* INS CRYPT, PAD_ZERO, 0, 16 */
+            *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        }
+        else
+        {
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+            /* INS NONE, PAD_ZERO, 0, 160 */
+            *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((160u)&0xffffu)<<0;
+#else
+            /* INS NONE, PAD_ZERO, 0, 16 */
+            *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+        }
+        /* DIR CRYPTHASH, paylen,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((paylen)&0x1ffffu)<<0;
+        /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* VERIFY icvlen,H */
+            *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,2,P */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+        }
+        else if (extseq == 1u)
+        {
+            /* VERIFY icvlen,H */
+            *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+        }
+        else
+        {
+            /* VERIFY icvlen,S,H */
+            *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 10: /* basic_crypto */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        ivlen = EVAL_ivlen();
+        if (packetsize < ivlen+bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic crypto\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 1: /* iv_inbound_cbc */
+            /* RETR NONE,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 2: /* iv_outbound_ctr */
+            /* INS  OUT,ORIG_IV1,8 */
+            *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 5: /* iv_copy_ctr */
+            /* RETR OUT,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 4: /* iv_copy_cbc */
+            /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            /* INS  OUT,ORIG_IV0,8 */
+            *tp++=0x21a00000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            /* INS  OUT,ORIG_IV0,16 */
+            *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+            break;
+        }
+        /* DIR CRYPT,packetsize-ivlen-bypass */
+        *tp++=0x05000000 | ((packetsize-ivlen-bypass)&0x1ffffu)<<0;
+        /* INS CRYPT,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASHPKT */
+        pad_bytes_basic = EVAL_pad_bytes_basic();
+        *tp++=0x2d060000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 1: /* upd_arc4 */
+            /* CTX ORIG_CHKSUM,iv_offset,1,P,F ; Update IJ pointer */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0ce3800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            /* CTX ORIG_CHKSUM_STORE,0,1,P,F   ; Update ARC4 state. */
+            *tp++=0xe0d63800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            break;
+        case 2: /* upd_iv2 */
+            /* CTX ORIG_IV0,iv_offset,2,P,F */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            break;
+        case 3: /* upd_iv4 */
+            /* CTX ORIG_IV0,iv_offset,4,P,F */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+            break;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 11: /* basic_hash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        appendhash = EVAL_appendhash();
+        if (antireplay > 0u)
+        {
+            /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+        else if (appendhash > 0u)
+        {
+            /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+            if (hstatelen > 16u)
+            {
+                /* CTX ORIG_SPI_RES,seq_offset+hstatelen-16,1,P,F ; Update block counter */
+                *tp++=0xe0c63800 | ((-16u+seq_offset+hstatelen)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            }
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 14: /* basic_crypthash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic crypthash\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt */
+                *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt */
+                *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 1: /* iv_inbound_cbc */
+            /* RETR HASHONLY,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x42a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 2: /* iv_outbound_ctr */
+            /* INS  HASH,ORIG_IV1,8 */
+            *tp++=0x23a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 5: /* iv_copy_ctr */
+            /* RETR HASH,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 4: /* iv_copy_cbc */
+            /* RETR HASH,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x43a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            /* INS  HASH,ORIG_IV0,8 */
+            *tp++=0x23a00000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            /* INS  HASH,ORIG_IV0,16 */
+            *tp++=0x23a00000 | ((16u)&0x1ffffu)<<0;
+            break;
+        }
+        pad_bytes_basic = EVAL_pad_bytes_basic();
+        if (pad_bytes_basic > 0u)
+        {
+            /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt-antireplay */
+            *tp++=0x07000000 | ((packetsize-ivlen-bypass-aadlen_pkt-antireplay)&0x1ffffu)<<0;
+            /* INS CRYPTHASH,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASH */
+            *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+        }
+        else
+        {
+            /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt-antireplay,LAST,LASTHASH */
+            *tp++=0x0f020000 | ((packetsize-ivlen-bypass-aadlen_pkt-antireplay)&0x1ffffu)<<0;
+        }
+        appendhash = EVAL_appendhash();
+        if (antireplay > 0u)
+        {
+            /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+        else if (appendhash > 0u)
+        {
+            /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+            if (hstatelen > 16u)
+            {
+                /* CTX ORIG_SPI_RES,seq_offset+hstatelen-16,1,P,F ; Update block counter */
+                *tp++=0xe0c63800 | ((-16u+seq_offset+hstatelen)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            }
+        }
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 1: /* upd_arc4 */
+            /* CTX ORIG_CHKSUM,iv_offset,1,P,F ; Update IJ pointer */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0ce3800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            /* CTX ORIG_CHKSUM_STORE,0,1,P,F   ; Update ARC4 state. */
+            *tp++=0xe0d63800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+            break;
+        case 2: /* upd_iv2 */
+            /* CTX ORIG_IV0,iv_offset,2,P,F */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+            break;
+        case 3: /* upd_iv4 */
+            /* CTX ORIG_IV0,iv_offset,4,P,F */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+            break;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 15: /* basic_out_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,4 */
+        *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+        /* DATA32 basic_salt */
+        basic_salt = EVAL_basic_salt();
+        *tp++=0x00000000 | ((basic_salt)&0xffffffffu)<<0;
+        if (ivhandling == 5u)
+        {
+            /* RETR HASH,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS HASH, ORIG_IV1,8 */
+            *tp++=0x23a80000 | ((8u)&0x1ffffu)<<0;
+        }
+        aadlen_swap = EVAL_aadlen_swap();
+        if (aadlen_swap > 0u)
+        {
+            /* INS HASHONLY,ORIG_TOKEN,6 */
+            *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+            /* DATA32 basic_swaplen */
+            basic_swaplen = EVAL_basic_swaplen();
+            *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+            /* DATA32 aadlen_swap */
+            *tp++=0x00000000 | ((aadlen_swap)&0xffffffffu)<<0;
+            aadlen_tkn = EVAL_aadlen_tkn();
+            if (aadlen_tkn > 0u)
+            {
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                    *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                    *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+                }
+                aad = EVAL_aad();
+                if (aadlen_tkn > 64)
+                {
+                    LOG_CRIT("Field too large\n");
+                    return TKB_BAD_FIELD_SIZE;
+                }
+                TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+                tp += (aadlen_tkn + 3)/4;
+            }
+            else if (aadlen_pkt > 0u)
+            {
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* DIR HASH,aadlen_pkt */
+                    *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* DIR HASHONLY,aadlen_pkt */
+                    *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+                }
+            }
+            /* INS HASHONLY,PAD_ZERO,0,aadpad */
+            aadpad = EVAL_aadpad();
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((aadpad)&0xffffu)<<0;
+        }
+        else
+        {
+            /* INS HASHONLY,ORIG_TOKEN,4 */
+            *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 basic_swaplen */
+            basic_swaplen = EVAL_basic_swaplen();
+            *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+        }
+        /* REMRES bypass+8+aadlen_out,16 */
+        aadlen_out = EVAL_aadlen_out();
+        *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT,PAD_ZERO,0,16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        basic_hashpad = EVAL_basic_hashpad();
+        if (basic_hashpad == 0u)
+        {
+            /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST,LASTHASH */
+            *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST */
+            *tp++=0x0f000000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+            /* INS HASHONLY,PAD_ZERO,0,basic_hashpad,LASTHASH */
+            *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((basic_hashpad)&0xffffu)<<0;
+        }
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 16: /* basic_in_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic in ccm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,4 */
+        *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+        /* DATA32 basic_salt */
+        basic_salt = EVAL_basic_salt();
+        *tp++=0x00000000 | ((basic_salt)&0xffffffffu)<<0;
+        if (ivhandling == 0u)
+        {
+            /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS HASHONLY,ORIG_IV1,8 */
+            *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+        }
+        aadlen_swap = EVAL_aadlen_swap();
+        if (aadlen_swap > 0u)
+        {
+            /* INS HASHONLY,ORIG_TOKEN,6 */
+            *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+            /* DATA32 basic_swaplen */
+            basic_swaplen = EVAL_basic_swaplen();
+            *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+            /* DATA32 aadlen_swap */
+            *tp++=0x00000000 | ((aadlen_swap)&0xffffffffu)<<0;
+            aadlen_tkn = EVAL_aadlen_tkn();
+            if (aadlen_tkn > 0u)
+            {
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                    *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                    *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+                }
+                aad = EVAL_aad();
+                if (aadlen_tkn > 64)
+                {
+                    LOG_CRIT("Field too large\n");
+                    return TKB_BAD_FIELD_SIZE;
+                }
+                TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+                tp += (aadlen_tkn + 3)/4;
+            }
+            else if (aadlen_pkt > 0u)
+            {
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* DIR HASH,aadlen_pkt */
+                    *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+                }
+                else
+                {
+                    /* DIR HASHONLY,aadlen_pkt */
+                    *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+                }
+            }
+            /* INS HASHONLY,PAD_ZERO,0,aadpad */
+            aadpad = EVAL_aadpad();
+            *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((aadpad)&0xffffu)<<0;
+        }
+        else
+        {
+            /* INS HASHONLY,ORIG_TOKEN,4 */
+            *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 basic_swaplen */
+            basic_swaplen = EVAL_basic_swaplen();
+            *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+        }
+        /* REMRES bypass+aadlen_out,16 */
+        aadlen_out = EVAL_aadlen_out();
+        *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT,PAD_ZERO,0,16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        basic_hashpad = EVAL_basic_hashpad();
+        if (basic_hashpad == 0u)
+        {
+            /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0f000000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+            /* INS HASHONLY,PAD_ZERO,0,basic_hashpad,LASTHASH */
+            *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((basic_hashpad)&0xffffu)<<0;
+        }
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 17: /* basic_out_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic out gcm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt,LAST */
+                *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt,LAST */
+                *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 5: /* iv_copy_ctr */
+            if (aadlen_pkt+aadlen_tkn == 0u)
+            {
+                LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* RETR OUT,ORIG_IV1,8 ; IV from input packet, copy iv */
+            *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            if (aadlen_pkt+aadlen_tkn == 0u)
+            {
+                LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv */
+            *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        default:
+            /* REMRES   bypass+aadlen_out,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      CRYPTHASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+        *tp++=0x0f020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 18: /* basic_in_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic in gcm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt,LAST */
+                *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt,LAST */
+                *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 5: /* iv_copy_ctr */
+            if (aadlen_pkt+aadlen_tkn == 0u)
+            {
+                LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* RETR OUT,ORIG_IV1,8 ; IV from input packet, copy iv */
+            *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            if (aadlen_pkt+aadlen_tkn == 0u)
+            {
+                LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv */
+            *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+            /* REMRES   bypass+aadlen_out+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        default:
+            /* REMRES   bypass+aadlen_out,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        /* INS      CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR      CRYPTHASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+        icvlen = EVAL_icvlen();
+        *tp++=0x0f020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 19: /* basic_out_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic out gmac\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt */
+                *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt */
+                *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 5: /* iv_copy_ctr */
+            /* RETR HASH,ORIG_IV1,8 ; IV from input packet, copy iv */
+            *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv. */
+            *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        default:
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        /* INS      CRYPT, PAD_ZERO, 0, 16,LAST */
+        *tp++=0x2d000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 20: /* basic_in_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic in gmac\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt */
+                *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt */
+                *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 0: /* iv_inbound_ctr */
+            /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+            *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 5: /* iv_copy_ctr */
+            /* RETR HASH,ORIG_IV1,8 ; IV from input packet, copy iv */
+            *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        case 15: /* iv_copy_token_4words */
+        case 2: /* iv_outbound_ctr */
+            /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv Do not authenticate IV */
+            *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen+8,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+            break;
+        default:
+            /* DIR      HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+            icvlen = EVAL_icvlen();
+            *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+            /* REMRES   packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen,16 */
+            aadlen_out = EVAL_aadlen_out();
+            *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        /* INS      CRYPT, PAD_ZERO, 0, 16,LAST */
+        *tp++=0x2d000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        seq_offset = EVAL_seq_offset();
+        if (seq_offset > 0u)
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+            hstatelen = EVAL_hstatelen();
+            *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        }
+        else
+        {
+            /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 23: /* basic_xts_crypto */
+#if TKB_HAVE_CRYPTO_XTS == 1u
+        ivlen = EVAL_ivlen();
+        if (packetsize < ivlen+bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic crypto\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        swap_j = EVAL_swap_j();
+        if (swap_j != 0u)
+        {
+            /* INSCTX NONE,ORIG_TOKEN,10,16 */
+            *tp++=0x90d80000 | ((10u)&0x1fu)<<12 | ((16u)&0x1ffu)<<0;
+            /* DATA32 0 */
+            *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+            /* DATA32 0 */
+            *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+            /* DATA32 0 */
+            *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+            /* DATA32 swap_j */
+            *tp++=0x00000000 | ((swap_j)&0xffffffffu)<<0;
+        }
+        switch(ivhandling)
+        {
+        case 1: /* iv_inbound_cbc */
+            /* RETR NONE,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 4: /* iv_copy_cbc */
+            /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            /* INS  OUT,ORIG_IV0,16 */
+            *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+            break;
+        }
+        /* DIR CRYPT,packetsize-ivlen-bypass */
+        *tp++=0x05000000 | ((packetsize-ivlen-bypass)&0x1ffffu)<<0;
+        /* INS CRYPT,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASHPKT */
+        pad_bytes_basic = EVAL_pad_bytes_basic();
+        *tp++=0x2d060000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+        upd_handling = EVAL_upd_handling();
+        switch(upd_handling)
+        {
+        case 0: /* upd_null */
+            break;
+        case 3: /* upd_iv4 */
+            /* CTX ORIG_IV0,iv_offset,4,P,F */
+            iv_offset = EVAL_iv_offset();
+            *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+            break;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 24: /* basic_kasumi_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,8 */
+        *tp++=0x22d80000 | ((8u)&0x1ffffu)<<0;
+        /* DATA32 count */
+        count = EVAL_count();
+        *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+        /* DATA32 bearer_dir_fresh */
+        bearer_dir_fresh = EVAL_bearer_dir_fresh();
+        *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        appendhash = EVAL_appendhash();
+        if (antireplay > 0u)
+        {
+            /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+        else if (appendhash > 0u)
+        {
+            /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 25: /* basic_snow_hash */
+    case 26: /* basic_zuc_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+        antireplay = EVAL_antireplay();
+        if (packetsize < bypass+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INSCTX NONE,ORIG_TOKEN,10,16 */
+        *tp++=0x90d80000 | ((10u)&0x1fu)<<12 | ((16u)&0x1ffu)<<0;
+        /* DATA32 count */
+        count = EVAL_count();
+        *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+        /* DATA32 bearer_dir_fresh */
+        bearer_dir_fresh = EVAL_bearer_dir_fresh();
+        *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+        /* DATA32 count */
+        *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+        /* DATA32 bearer_dir_fresh */
+        *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+            *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+        }
+        appendhash = EVAL_appendhash();
+        if (antireplay > 0u)
+        {
+            /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+            *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+            /* VERIFY antireplay,H */
+            *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+        }
+        else if (appendhash > 0u)
+        {
+            /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+            icvlen = EVAL_icvlen();
+            *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 27: /* basic_hashenc */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic crypthash\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+                *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt */
+                *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt */
+                *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        switch(ivhandling)
+        {
+        case 4: /* iv_copy_cbc */
+            /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+            *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+            break;
+        case 6: /* iv_outbound_2words */
+        case 9: /* iv_copy_token_2words */
+            /* INS  OUT,ORIG_IV0,8 */
+            *tp++=0x21a00000 | ((8u)&0x1ffffu)<<0;
+            break;
+        case 7: /* iv_outbound_4words */
+        case 15: /* iv_copy_token_4words */
+            /* INS  OUT,ORIG_IV0,16 */
+            *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+            break;
+        }
+        /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt,LASTHASH */
+        *tp++=0x07020000 | ((packetsize-ivlen-bypass-aadlen_pkt)&0x1ffffu)<<0;
+        /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+        icvlen = EVAL_icvlen();
+        *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+        /* INS CRYPT,PAD_TLS,0,pad_bytes_hashenc,LAST,LASTHASHPKT */
+        pad_bytes_hashenc = EVAL_pad_bytes_hashenc();
+        *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes_hashenc)&0x1ffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 28: /* basic_dechash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_pkt+aadlen_tkn < 2u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, aad too short\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* REMRES 0,4,NOUPDCHK */
+        *tp++=0xa0020000 | ((0u)&0xffffu)<<0 | ((4u)&0x3fu)<<19;
+        cipher_is_aes = EVAL_cipher_is_aes();
+        if (cipher_is_aes == 0u)
+        {
+            ivlen = EVAL_ivlen();
+            if (packetsize < 16u+bypass+aadlen_pkt+ivlen)
+            {
+                LOG_WARN("TokenBuilder: bad packet, too short for basic dechash\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* INS CRYPTONLY,ORIG_TOKEN,12 */
+            *tp++=0x24d80000 | ((12u)&0x1ffffu)<<0;
+            ssltls_lastblock = EVAL_ssltls_lastblock();
+            TokenBuilder_CopyBytes(tp, ssltls_lastblock, 12);
+            tp += 3;
+            /* INS CRYPT,ORIG_TOKEN,4 */
+            *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+            ssltls_lastword = EVAL_ssltls_lastword();
+            TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+            tp += 1;
+        }
+        else
+        {
+            ivlen = EVAL_ivlen();
+            if (packetsize < 32u+bypass+aadlen_pkt+ivlen)
+            {
+                LOG_WARN("TokenBuilder: bad packet, too short for basic dechash\n");
+                rc = TKB_BAD_PACKET; goto error;
+            }
+            /* INS CRYPTONLY,ORIG_TOKEN,28 */
+            *tp++=0x24d80000 | ((28u)&0x1ffffu)<<0;
+            ssltls_lastblock = EVAL_ssltls_lastblock();
+            TokenBuilder_CopyBytes(tp, ssltls_lastblock, 28);
+            tp += 7;
+            /* INS CRYPT,ORIG_TOKEN,4 */
+            *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+            ssltls_lastword = EVAL_ssltls_lastword();
+            TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+            tp += 1;
+        }
+        /* DIR NONE,0,LAST */
+        *tp++=0x08000000 | ((0u)&0x1ffffu)<<0;
+        if (bypass > 0u)
+        {
+            /* DIR OUT,bypass */
+            *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+        }
+        if (aadlen_tkn > 0u)
+        {
+            /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn-2 */
+            *tp++=0x22d80000 | ((-2u+aadlen_tkn)&0x1ffffu)<<0;
+            aad = EVAL_aad();
+            if (-2u+aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, -2u+aadlen_tkn);
+            tp += (-2u+aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            /* DIR HASHONLY,aadlen_pkt-2 */
+            *tp++=0x02000000 | ((-2u+aadlen_pkt)&0x1ffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_LENCOR,packetsize-bypass-aadlen_pkt-ivlen-icvlen-1 */
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        *tp++=0x22780000 | ((-1u+packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+        /* REM 2 */
+        *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+        if (ivlen > 0u)
+        {
+            /* RETR NONE,ORIG_IV0,ivlen */
+            *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+        }
+        /* REMRES bypass,icvlen,NOUPDCHK          ; Cause the MAC to be removed */
+        *tp++=0xa0020000 | ((bypass)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+        /* DIRX CRYPTHASH,ORIG_LENCOR,0,LASTHASH */
+        *tp++=0x077a0000 | ((0u)&0x1ffffu)<<0;
+        /* DIRX CRYPT,ORIG_LENCOR,icvlen+1,LAST,LASTHASHPKT */
+        *tp++=0x0d7e0000 | ((1u+icvlen)&0x1ffffu)<<0;
+        /* VERIFY icvlen,P,H */
+        *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 12: /* srtp_out */
+#if TKB_HAVE_PROTO_SRTP == 1u
+        srtp_offset = EVAL_srtp_offset();
+        if (packetsize <= bypass+srtp_offset)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SRTP outbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (srtp_offset > 0u)
+        {
+            /* DIR  HASH, srtp_offset */
+            *tp++=0x03000000 | ((srtp_offset)&0x1ffffu)<<0;
+            /* DIR  CRYPTHASH, packetsize - bypass - srtp_offset,LAST */
+            *tp++=0x0f000000 | ((packetsize-bypass-srtp_offset)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR  HASH, packetsize - bypass,LAST */
+            *tp++=0x0b000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        }
+        extseq = EVAL_extseq();
+        if (extseq > 0u)
+        {
+            /* INS  HASH, ORIG_TOKEN, 4, LASTHASH ; SCTCP, index gets appended */
+            *tp++=0x23da0000 | ((4u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS  HASHONLY, ORIG_TOKEN, 4, LASTHASH ; SRTP, ROC gets hashed, not appended */
+            *tp++=0x22da0000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* DATA32 srtp_swaproc */
+        srtp_swaproc = EVAL_srtp_swaproc();
+        *tp++=0x00000000 | ((srtp_swaproc)&0xffffffffu)<<0;
+        antireplay = EVAL_antireplay();
+        if (antireplay > 0u)
+        {
+            /* INS OUT,ORIG_SPI,4,LASTHASH */
+            *tp++=0x21920000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS OUT, ORIG_HASH, icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 13: /* srtp_in */
+#if TKB_HAVE_PROTO_SRTP == 1u
+        srtp_offset = EVAL_srtp_offset();
+        icvlen = EVAL_icvlen();
+        extseq = EVAL_extseq();
+        antireplay = EVAL_antireplay();
+        if (packetsize <= bypass+srtp_offset+icvlen+extseq+antireplay)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SRTP inbound\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (srtp_offset > 0u)
+        {
+            /* DIR  HASH, srtp_offset */
+            *tp++=0x03000000 | ((srtp_offset)&0x1ffffu)<<0;
+            /* DIR CRYPTHASH, packetsize - bypass - srtp_offset - icvlen - extseq -antireplay,LAST */
+            *tp++=0x0f000000 | ((packetsize-bypass-srtp_offset-icvlen-extseq-antireplay)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* DIR HASH, packetsize - bypass - icvlen - extseq -antireplay,LAST */
+            *tp++=0x0b000000 | ((packetsize-bypass-icvlen-extseq-antireplay)&0x1ffffu)<<0;
+        }
+        if (extseq > 0u)
+        {
+            /* DIR  HASHONLY, 4, LASTHASH ; SCTCP extraxt from packet. */
+            *tp++=0x02020000 | ((4u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS  HASHONLY, ORIG_TOKEN, 4, LASTHASH ; SRTP, ROC gets hashed, not appended */
+            *tp++=0x22da0000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 srtp_swaproc */
+            srtp_swaproc = EVAL_srtp_swaproc();
+            *tp++=0x00000000 | ((srtp_swaproc)&0xffffffffu)<<0;
+        }
+        if (antireplay > 0u)
+        {
+            /* RETR NONE,ORIG_SPI,4 */
+            *tp++=0x40900000 | ((4u)&0x1ffffu)<<0;
+        }
+        if (icvlen > 0u)
+        {
+            /* RETR NONE,ORIG_HASH, icvlen,LASTHASHPKT */
+            *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+            if (antireplay > 0u)
+            {
+                /* VERIFY icvlen,H,SP */
+                *tp++=0xd4070000 | ((icvlen)&0x7fu)<<0;
+            }
+            else
+            {
+                /* VERIFY icvlen,H */
+                *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+            }
+        }
+        else
+        {
+            /* INS NONE,PAD_ZERO,0,0,LASTHASHPKT */
+            *tp++=0x20060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+            if (antireplay > 0u)
+            {
+                /* VERIFY 0,SP */
+                *tp++=0xd4060000 | ((0u)&0x7fu)<<0;
+            }
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 29: /* basic_out_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt,LAST */
+                *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt,LAST */
+                *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        else
+        {
+            /* INS HASHONLY,PAD_ZERO,0,0,LAST */
+            *tp++=0x2a000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+        /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad crypto\n");
+        rc = TKB_BAD_CRYPTO; goto error;
+#endif
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 30: /* basic_in_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+        aadlen_pkt = EVAL_aadlen_pkt();
+        ivlen = EVAL_ivlen();
+        if (packetsize < bypass+aadlen_pkt+ivlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        aadlen_tkn = EVAL_aadlen_tkn();
+        if (aadlen_tkn > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+                *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+            }
+            aad = EVAL_aad();
+            if (aadlen_tkn > 64)
+            {
+                LOG_CRIT("Field too large\n");
+                return TKB_BAD_FIELD_SIZE;
+            }
+            TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+            tp += (aadlen_tkn + 3)/4;
+        }
+        else if (aadlen_pkt > 0u)
+        {
+            extseq = EVAL_extseq();
+            if (extseq > 0u)
+            {
+                /* DIR HASH,aadlen_pkt,LAST */
+                *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* DIR HASHONLY,aadlen_pkt,LAST */
+                *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+            }
+        }
+        else
+        {
+            /* INS HASHONLY,PAD_ZERO,0,0,LAST */
+            *tp++=0x2a000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+        /* INS NONE,PAD_ZERO,0,176 */
+        *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((176u)&0xffffu)<<0;
+#else
+        /* INS NONE,PAD_ZERO,0,16 */
+        *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+        /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST,LASTHASH */
+        icvlen = EVAL_icvlen();
+        *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+        /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+        antireplay = EVAL_antireplay();
+        *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+        /* VERIFY antireplay,H */
+        *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad crypto\n");
+        rc = TKB_BAD_CRYPTO; goto error;
+#endif
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 31: /* tls13_gcm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASH,PAD_CONST,0x17,1    ; Type field */
+        *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASH,ORIG_SPI,2          ; For TLS1.3 hash fixed type/version field. */
+        *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        /* INS HASH,ORIG_TOKEN,2,LAST */
+        *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen_tls13    ; Fragment length to output and hash. */
+        swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+        *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+        /* REMRES bypass + 5, 16 */
+        *tp++=0xa0000000 | ((5u+bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass */
+        *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        count = EVAL_count();
+        if (count == 0u)
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1, LAST, LASTHASH */
+            nextheader = EVAL_nextheader();
+            *tp++=0x2f120000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+            nextheader = EVAL_nextheader();
+            *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+            /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST, LASTHASH */
+            *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+        }
+        /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2 */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 32: /* tls13_gcm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        icvlen = EVAL_icvlen();
+        if (packetsize < 5u+bypass+icvlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* DIR HASHONLY,5,LAST       ; Hash type and version number and length */
+        *tp++=0x0a000000 | ((5u)&0x1ffffu)<<0;
+        /* REMRES bypass, 16 */
+        *tp++=0xa0000000 | ((bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+        /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY icvlen,H */
+        *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2,P */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 33: /* tls13_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASH,PAD_CONST,0x17,1    ; Type field */
+        *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASH,ORIG_SPI,2          ; For TLS1.3 hash fixed type/version field. */
+        *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        /* INS HASH,ORIG_TOKEN,2,LAST */
+        *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen_tls13    ; Fragment length to output and hash. */
+        swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+        *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass */
+        *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        count = EVAL_count();
+        if (count == 0u)
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1, LAST, LASTHASH */
+            nextheader = EVAL_nextheader();
+            *tp++=0x2f120000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+            nextheader = EVAL_nextheader();
+            *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+            /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST, LASTHASH */
+            *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+        }
+        /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2 */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 34: /* tls13_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        icvlen = EVAL_icvlen();
+        if (packetsize < 5u+bypass+icvlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* DIR HASHONLY,5,LAST       ; Hash type and version number and length */
+        *tp++=0x0a000000 | ((5u)&0x1ffffu)<<0;
+        /* INS NONE, PAD_ZERO, 0, 16 */
+        *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+        /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY icvlen,H */
+        *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2,P */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 35: /* esp_out_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        if (packetsize <= bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* INS      HASH,ORIG_SPI,8,LAST */
+            *tp++=0x2b900000 | ((8u)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS      HASH,ORIG_SPI,4 */
+            *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASH,ORIG_SEQNUM_RES, 4, LAST */
+            *tp++=0x2b980000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS      OUT,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+        /* DIR      CRYPTHASH, packetsize-bypass-hdrlen */
+        *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        /* INS      CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+        nextheader = EVAL_nextheader();
+        pad_bytes = EVAL_pad_bytes();
+        *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+        /* INS      OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX      ORIG_SEQNUM,seq_offset,1+extseq */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 36: /* esp_in_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+        ivlen = EVAL_ivlen();
+        icvlen = EVAL_icvlen();
+        pad_blocksize = EVAL_pad_blocksize();
+        if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        pad_remainder = EVAL_pad_remainder();
+        if (pad_remainder != 0u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound ChaChaPoly\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        extseq = EVAL_extseq();
+        if (extseq != 1u)
+        {
+            /* RETR     HASHONLY,ORIG_SPI,8,LAST */
+            *tp++=0x4a900000 | ((8u)&0x1ffffu)<<0;
+            /* RETR     NONE,ORIG_IV1,ivlen */
+            *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+#if TKB_HAVE_ECN_FIXUP == 1u
+            /* DATA32 ecn_fixup_instr */
+            ecn_fixup_instr = EVAL_ecn_fixup_instr();
+            *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+            /* INS      NONE, PAD_ZERO, 0, 16 */
+            *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        }
+        else
+        {
+            /* RETR     HASHONLY,ORIG_SPI,4 */
+            *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+            /* RETR     NONE,ORIG_SEQNUM_RES,4 */
+            *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+            /* RETR     NONE,ORIG_IV1,ivlen */
+            *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS      HASHONLY,ORIG_SEQNUM_RES,4,LAST */
+            *tp++=0x2a980000 | ((4u)&0x1ffffu)<<0;
+#if TKB_HAVE_ECN_FIXUP == 1u
+            /* DATA32 ecn_fixup_instr */
+            ecn_fixup_instr = EVAL_ecn_fixup_instr();
+            *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+            /* INS      NONE, PAD_ZERO, 0, 160 */
+            *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((160u)&0xffffu)<<0;
+#else
+            /* INS      NONE, PAD_ZERO, 0, 16 */
+            *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+        }
+        /* DIR      CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+        *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+        /* RETR     NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 39: /* ssltls_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass+hdrlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound CCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (hdrlen > 0u)
+        {
+            /* DIR OUT,hdrlen */
+            *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+        }
+        capwap_out = EVAL_capwap_out();
+        if (capwap_out != 0u)
+        {
+            /* INS OUT,ORIG_TOKEN,4 */
+            *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+            /* DATA32 0x0000001  ; Insert DTLS/CAPWAP header. */
+            *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+        }
+        /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+        salt = EVAL_salt();
+        *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASHONLY,ORIG_IV0,4 */
+        *tp++=0x22a00000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+        *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_SEQNUM,4 */
+        *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_TOKEN,5 */
+        *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+        /* DATA32 swaplen3                 ; 3-byte length in b0 block. */
+        swaplen3 = EVAL_swaplen3();
+        *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+        /* DATA32 0x0d                     ; and swapped 2-byte AAD length just after */
+        *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+        /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+        *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_SEQNUM,4 */
+        *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+        /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+        nextheader = EVAL_nextheader();
+        *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASH,ORIG_SPI,2          ; For TLS/DTLS, hash version field. */
+        *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq != 0u)
+        {
+            /* INS OUT,ORIG_EXTSEQNUM,4 ; Output sequence number for DTLS */
+            *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+            /* INS OUT,ORIG_SEQNUM,4 */
+            *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS HASHONLY,ORIG_TOKEN,2 */
+        *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swaplen                   ; Payload length to hash. */
+        swaplen = EVAL_swaplen();
+        *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        /* INS HASHONLY,PAD_ZERO,0,1        ; Pad AAD to 16 bytes. */
+        *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((1u)&0xffffu)<<0;
+        /* INS OUT,ORIG_TOKEN,2 */
+        *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen              ; Fragment length to output. */
+        swap_fraglen = EVAL_swap_fraglen();
+        *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+        /* INS OUT,ORIG_IV1,ivlen */
+        ivlen = EVAL_ivlen();
+        *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+        if (extseq != 0u)
+        {
+            /* REMRES bypass + hdrlen + capwap_out + 5 + 8 + 8, 16 */
+            *tp++=0xa0000000 | ((21u+bypass+hdrlen+capwap_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        else
+        {
+            /* REMRES bypass + hdrlen + 5 + 8, 16 */
+            *tp++=0xa0000000 | ((13u+bypass+hdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        }
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        if (packetsize != bypass+hdrlen)
+        {
+            /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LAST */
+            *tp++=0x0f000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_ZERO, 0, 0,LAST */
+            *tp++=0x2f000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        }
+        /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+        hashpad = EVAL_hashpad();
+        *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+        /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2 */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 40: /* ssltls_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        paylen = EVAL_paylen();
+        if (paylen == 4294967295u)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound CCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        if (hdrlen > 0u)
+        {
+            /* DIR OUT,hdrlen */
+            *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+        }
+        capwap_in = EVAL_capwap_in();
+        if (capwap_in != 0u)
+        {
+            /* REM 4  ; Remove DTLS/CAPWAP header. */
+            *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+        }
+        /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+        salt = EVAL_salt();
+        *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASHONLY,ORIG_IV0,4 */
+        *tp++=0x22a00000 | ((4u)&0x1ffffu)<<0;
+        ohdrlen = EVAL_ohdrlen();
+        if (ohdrlen > hdrlen)
+        {
+            /* RETR OUT,ORIG_SPI,3    ; Extract Type and Version. */
+            *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+            /* RETR NONE,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+            *tp++=0x40480000 | ((4u)&0x1ffffu)<<0;
+            /* RETR NONE,ORIG_SEQNUM_RES2,4 */
+            *tp++=0x40400000 | ((4u)&0x1ffffu)<<0;
+            /* REM 2                    ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            /* RETR HASHONLY,ORIG_IV1,ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_TOKEN,5 */
+            *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+            /* DATA32 swaplen3                 ; 3-byte length in b0 block. */
+            swaplen3 = EVAL_swaplen3();
+            *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+            /* DATA32 0x0d                     ; and swapped 2-byte AAD length just after */
+            *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+            /* INS HASHONLY, ORIG_EXTSEQNUM_RES2,4 */
+            *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+            /* INS HASHONLY, ORIG_SEQNUM_RES2,4 */
+            *tp++=0x22400000 | ((4u)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+            *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+            /* INS HASH,ORIG_TOKEN,2 */
+            *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+            /* DATA32 swaplen */
+            swaplen = EVAL_swaplen();
+            *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+            if (ohdrlen-hdrlen > 5u)
+            {
+                /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+                *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+            }
+        }
+        else
+        {
+            /* RETR NONE,ORIG_SPI,3    ; Extract Type and Version. */
+            *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+            extseq = EVAL_extseq();
+            if (extseq != 0u)
+            {
+                /* RETR NONE,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+                *tp++=0x40480000 | ((4u)&0x1ffffu)<<0;
+                /* RETR NONE,ORIG_SEQNUM_RES2,4 */
+                *tp++=0x40400000 | ((4u)&0x1ffffu)<<0;
+            }
+            /* REM 2                    ; Remove fragment length. */
+            *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+            /* RETR HASHONLY,ORIG_IV1,ivlen */
+            ivlen = EVAL_ivlen();
+            *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_TOKEN,5 */
+            *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+            /* DATA32 swaplen3                 ; 3-byte length in b0 block. */
+            swaplen3 = EVAL_swaplen3();
+            *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+            /* DATA32 0x0d                     ; and swapped 2-byte AAD length just after */
+            *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+            if (extseq != 0u)
+            {
+                /* INS HASHONLY,ORIG_EXTSEQNUM_RES2,4  ; Extract from SA. */
+                *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_SEQNUM_RES2,4 */
+                *tp++=0x22400000 | ((4u)&0x1ffffu)<<0;
+            }
+            else
+            {
+                /* INS HASHONLY,ORIG_EXTSEQNUM,4  ; Extract from SA. */
+                *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+                /* INS HASHONLY,ORIG_SEQNUM,4 */
+                *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+            }
+            /* INS HASHONLY,ORIG_SPI_RES,3  ; Hash type and version. */
+            *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+            /* INS HASHONLY,ORIG_TOKEN,2 */
+            *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+            /* DATA32 swaplen */
+            swaplen = EVAL_swaplen();
+            *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+        }
+        /* INS HASHONLY,PAD_ZERO,0,1      ; Pad AAD to 16 bytes. */
+        *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((1u)&0xffffu)<<0;
+        /* REMRES bypass+ohdrlen, 16 */
+        *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, paylen,LAST */
+        *tp++=0x0f000000 | ((paylen)&0x1ffffu)<<0;
+        /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+        hashpad = EVAL_hashpad();
+        *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+        /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        extseq = EVAL_extseq();
+        if (extseq == 0u)
+        {
+            /* VERIFY icvlen,H */
+            *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,2,P */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+        }
+        else if (extseq == 1u)
+        {
+            /* VERIFY icvlen,H */
+            *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+        }
+        else
+        {
+            /* VERIFY icvlen,S,H */
+            *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+            /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+            seq_offset = EVAL_seq_offset();
+            *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+        }
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 41: /* tls13_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+        salt = EVAL_salt();
+        *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASHONLY,ORIG_IV0,12 */
+        *tp++=0x22a00000 | ((12u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_TOKEN,5 */
+        *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+        /* DATA32 swaplen3_tls13_out       ; 3-byte length in b0 block. */
+        swaplen3_tls13_out = EVAL_swaplen3_tls13_out();
+        *tp++=0x00000000 | ((swaplen3_tls13_out)&0xffffffffu)<<0;
+        /* DATA32 0x05                     ; and swapped 2-byte AAD length just after */
+        *tp++=0x00000000 | ((5u)&0xffffffffu)<<0;
+        /* INS HASH,PAD_CONST,0x17,1    ; Type field */
+        *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASH,ORIG_SPI,2          ; For TLS1.3 hash fixed type/version field. */
+        *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+        /* INS HASH,ORIG_TOKEN,2 */
+        *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+        /* DATA32 swap_fraglen_tls13     ; Fragment length to output and hash. */
+        swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+        *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+        /* INS HASHONLY,PAD_ZERO,0,9     ; Pad AAD block */
+        *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((9u)&0xffffu)<<0;
+        /* REMRES bypass + 5, 16 */
+        *tp++=0xa0000000 | ((5u+bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass */
+        *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        count = EVAL_count();
+        if (count == 0u)
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1,LAST */
+            nextheader = EVAL_nextheader();
+            *tp++=0x2f100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        }
+        else
+        {
+            /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+            nextheader = EVAL_nextheader();
+            *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+            /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST */
+            *tp++=0x2f000000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+        }
+        /* INS HASHONLY,PAD_ZERO, 0, hashpad_tls13_out, LASTHASH */
+        hashpad_tls13_out = EVAL_hashpad_tls13_out();
+        *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad_tls13_out)&0xffffu)<<0;
+        /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+        icvlen = EVAL_icvlen();
+        *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY   0  ; Causes any sequence number rollover error to fail the packet. */
+        *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2 */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 42: /* tls13_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+        icvlen = EVAL_icvlen();
+        if (packetsize < 5u+bypass+icvlen)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+        salt = EVAL_salt();
+        *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+        /* INS HASHONLY,ORIG_IV0,12 */
+        *tp++=0x22a00000 | ((12u)&0x1ffffu)<<0;
+        /* INS HASHONLY,ORIG_TOKEN,5 */
+        *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+        /* DATA32 swaplen3_tls13_in        ; 3-byte length in b0 block. */
+        swaplen3_tls13_in = EVAL_swaplen3_tls13_in();
+        *tp++=0x00000000 | ((swaplen3_tls13_in)&0xffffffffu)<<0;
+        /* DATA32 0x05                     ; and swapped 2-byte AAD length just after */
+        *tp++=0x00000000 | ((5u)&0xffffffffu)<<0;
+        /* DIR HASHONLY,5                  ; Hash type and version number and length */
+        *tp++=0x02000000 | ((5u)&0x1ffffu)<<0;
+        /* INS HASHONLY,PAD_ZERO,0,9       ; Pad AAD block */
+        *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((9u)&0xffffu)<<0;
+        /* REMRES bypass, 16 */
+        *tp++=0xa0000000 | ((bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+        /* INS CRYPT, PAD_ZERO, 0, 16 */
+        *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+        /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST */
+        *tp++=0x0f000000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+        /* INS HASHONLY,PAD_ZERO, 0, hashpad_tls13_in, LASTHASH */
+        hashpad_tls13_in = EVAL_hashpad_tls13_in();
+        *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad_tls13_in)&0xffffu)<<0;
+        /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+        *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+        /* VERIFY icvlen,H */
+        *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+        /* CTX ORIG_SEQNUM,seq_offset,2,P */
+        seq_offset = EVAL_seq_offset();
+        *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 43: /* basic_hmac_precompute */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic hash precompute\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* DIR HASHONLY,packetsize-bypass,LASTHASH */
+        *tp++=0x02020000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        /* INS OUT, ORIG_HASH,hstatelen_bytes */
+        hstatelen_bytes = EVAL_hstatelen_bytes();
+        *tp++=0x21e00000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+        /* INS NONE,PAD_ZERO, 0, 0 */
+        *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        /* INS OUT,ORIG_HASH,hstatelen_bytes,LASTHASHPKT */
+        *tp++=0x21e60000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 44: /* basic_hmac_ctxprepare */
+#if TKB_HAVE_PROTO_BASIC == 1u
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic hash precompute\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* DIR HASHONLY,packetsize-bypass,LASTHASH */
+        *tp++=0x02020000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        /* INS NONE, ORIG_HASH,hstatelen_bytes */
+        hstatelen_bytes = EVAL_hstatelen_bytes();
+        *tp++=0x20e00000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+        /* INS NONE,PAD_ZERO, 0, 0 */
+        *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+        /* INS NONE,ORIG_HASH,hstatelen_bytes,LASTHASHPKT */
+        *tp++=0x20e60000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+        /* CTX ORIG_HASH_INNER,digest_offset,hstatelen,P,F */
+        digest_offset = EVAL_digest_offset();
+        hstatelen = EVAL_hstatelen();
+        *tp++=0xe0ee3800 | ((digest_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+        /* CTX ORIG_HASH,digest_offset+hstatelen,hstatelen,P,F */
+        *tp++=0xe0e63800 | ((digest_offset+hstatelen)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+#else
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+        break;
+    case 45: /* basic_bypass */
+        if (packetsize < bypass)
+        {
+            LOG_WARN("TokenBuilder: bad packet, too short for basic bypass\n");
+            rc = TKB_BAD_PACKET; goto error;
+        }
+        /* DIR OUT,packetsize-bypass,LASTHASHPKT */
+        *tp++=0x01060000 | ((packetsize-bypass)&0x1ffffu)<<0;
+        break;
+    default:
+        LOG_WARN("TokenBuilder: bad protocol\n");
+        rc = TKB_BAD_PROTOCOL; goto error;
+    }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+    hproto = EVAL_hproto();
+    switch(hproto)
+    {
+    case 6: /* ipv4_in_transp */
+    case 26: /* ipv4_in_transp_natt */
+        /* INSRES 2+bypass,7,L,NH,CS,LASTINS */
+        *tp++=0xae050000 | ((2u+bypass)&0xffffu)<<0 | ((7u)&0x3fu)<<19;
+        break;
+    case 12: /* ipv6_in_transp */
+    case 32: /* ipv6_in_transp_natt */
+        /* INSRES 4+bypass,40,L,NOUPDCHK */
+        *tp++=0xa8030000 | ((4u+bypass)&0xffffu)<<0 | ((40u)&0x3fu)<<19;
+        /* INSRES bypass+prev_nhoffset,0,NH,NOUPDCHK,LASTINS */
+        prev_nhoffset = EVAL_prev_nhoffset();
+        *tp++=0xa4070000 | ((bypass+prev_nhoffset)&0xffffu)<<0 | ((0u)&0x3fu)<<19;
+        break;
+    }
+#endif
+    switch(proto)
+    {
+    case 1: /* esp_in */
+    case 3: /* esp_in_ccm */
+    case 5: /* esp_in_gcm */
+    case 7: /* esp_in_gmac */
+    case 36: /* esp_in_chachapoly */
+        icvlen = EVAL_icvlen();
+        if (icvlen > 0u)
+        {
+            antireplay = EVAL_antireplay();
+            if (antireplay > 12u)
+            {
+                /* VERIFY   icvlen,S,SP,P,H */
+                *tp++=0xdd070000 | ((icvlen)&0x7fu)<<0;
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* CTX     ORIG_SEQNUM,seq_offset,0,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((0u)&0xfu)<<24;
+                }
+                else
+                {
+                    /* CTX     ORIG_SEQNUM_INBOUND,seq_offset,0,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe02e1800 | ((seq_offset)&0xffu)<<0 | ((0u)&0xfu)<<24;
+                }
+            }
+            else if (antireplay != 0u)
+            {
+                /* VERIFY   icvlen,S,SP,P,H */
+                *tp++=0xdd070000 | ((icvlen)&0x7fu)<<0;
+                extseq = EVAL_extseq();
+                if (extseq > 0u)
+                {
+                    /* CTX     ORIG_SEQNUM,seq_offset,2+antireplay,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u+antireplay)&0xfu)<<24;
+                }
+                else
+                {
+                    /* CTX     ORIG_SEQNUM_INBOUND,seq_offset,1+antireplay,P */
+                    seq_offset = EVAL_seq_offset();
+                    *tp++=0xe02e1800 | ((seq_offset)&0xffu)<<0 | ((1u+antireplay)&0xfu)<<24;
+                }
+            }
+            else
+            {
+                /* VERIFY   icvlen,SP,P,H */
+                *tp++=0xd5070000 | ((icvlen)&0x7fu)<<0;
+            }
+        }
+        else
+        {
+            /* VERIFY   0,SP,P */
+            *tp++=0xd5060000 | ((0u)&0x7fu)<<0;
+        }
+        break;
+    }
+#endif
+
+
+    Switch_Proto(TokenContext_Internal_p);
+
+error:
+    if (rc != TKB_STATUS_OK)
+    {
+        tp = (uint32_t *)Token_p + TKB_TOKEN_HEADER_WORD_COUNT;
+        /* Include CCW0 and CCW1 in token. */
+        *tp++ = 0;
+        *tp++ = 0;
+        /* DIR OUT,PacketByteCount,LASTHASHPKT pass packet unchanged */
+        *tp++ = 0x01060000 | (PacketByteCount & 0x1ffff);
+        *TokenHeaderWord_p = TKB_HEADER_DEFAULT | TKB_HEADER_C | (PacketByteCount & 0x1ffff);
+    }
+    *TokenWord32Count_p = tp - (uint32_t*)Token_p;
+    return rc;
+}
+
+/* end of file token_builder_core.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c
new file mode 100644
index 0000000..753a1cb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c
@@ -0,0 +1,567 @@
+/* eip201_sl.c
+ *
+ * Driver Library for the Security-IP-201 Advanced Interrupt Controller.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// Top-level Interrupt controller configuration
+#include "c_eip201.h"           // configuration
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"         // uint32_t, inline, etc.
+
+// Interrupt controller API
+#include "eip201.h"             // the API we will implement
+
+// Driver Framework Device API
+#include "device_rw.h"          // Device_Read32/Write32
+
+// create a constant where all unused interrupts are '1'
+#if (EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS < 32)
+#define EIP201_NOTUSEDIRQ_MASK (uint32_t) \
+                    (~((1 << EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS)-1))
+#else
+#define EIP201_NOTUSEDIRQ_MASK 0
+#endif
+
+#ifdef EIP201_STRICT_ARGS
+#define EIP201_CHECK_IF_IRQ_SUPPORTED(_irqs) \
+        if (_irqs & EIP201_NOTUSEDIRQ_MASK) \
+            return EIP201_STATUS_UNSUPPORTED_IRQ;
+#else
+#define EIP201_CHECK_IF_IRQ_SUPPORTED(_irqs)
+#endif /* EIP201_STRICT_ARGS */
+
+
+/*----------------------------------------------------------------------------
+ *  EIP201 registers
+ */
+enum
+{
+    EIP201_REGISTER_OFFSET_POL_CTRL     = EIP201_LO_REG_BASE+0,
+    EIP201_REGISTER_OFFSET_TYPE_CTRL    = EIP201_LO_REG_BASE+4,
+    EIP201_REGISTER_OFFSET_ENABLE_CTRL  = EIP201_LO_REG_BASE+8,
+    EIP201_REGISTER_OFFSET_RAW_STAT     = EIP201_HI_REG_BASE+12,
+    EIP201_REGISTER_OFFSET_ENABLE_SET   = EIP201_LO_REG_BASE+12,
+    EIP201_REGISTER_OFFSET_ENABLED_STAT = EIP201_HI_REG_BASE+16,
+    EIP201_REGISTER_OFFSET_ACK          = EIP201_LO_REG_BASE+16,
+    EIP201_REGISTER_OFFSET_ENABLE_CLR   = EIP201_LO_REG_BASE+20,
+    EIP201_REGISTER_OFFSET_OPTIONS      = EIP201_HI_REG_BASE+24,
+    EIP201_REGISTER_OFFSET_VERSION      = EIP201_HI_REG_BASE+28
+};
+
+// this implementation supports only the EIP-201 HW1.1 and HW1.2
+// 0xC9  = 201
+// 0x39  = binary inverse of 0xC9
+#define EIP201_SIGNATURE      0x36C9
+#define EIP201_SIGNATURE_MASK 0xffff
+
+/*----------------------------------------------------------------------------
+ * EIP201_Read32
+ *
+ * This routine reads from a Register location in the EIP201, applying
+ * endianness swapping when required (depending on configuration).
+ */
+static inline int
+EIP201_Read32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        uint32_t * const Value_p)
+{
+    return Device_Read32Check(Device, Offset, Value_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Write32
+ *
+ * This routine writes to a Register location in the EIP201, applying
+ * endianness swapping when required (depending on configuration).
+ */
+static inline int
+EIP201_Write32(
+        Device_Handle_t Device,
+        const unsigned int Offset,
+        const uint32_t Value)
+{
+    return Device_Write32(Device, Offset, Value);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Config_Change
+ */
+#ifndef EIP201_REMOVE_CONFIG_CHANGE
+EIP201_Status_t
+EIP201_Config_Change(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources,
+        const EIP201_Config_t Config)
+{
+    uint32_t Value;
+    uint32_t NewPol = 0;
+    uint32_t NewType = 0;
+    int rc;
+    EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+    /*
+        EIP201_CONFIG_ACTIVE_LOW,       // Type=0, Pol=0
+        EIP201_CONFIG_ACTIVE_HIGH,      // Type=0, Pol=1
+        EIP201_CONFIG_FALLING_EDGE,     // Type=1, Pol=0
+        EIP201_CONFIG_RISING_EDGE       // Type=1, Pol=1
+    */
+
+    // do we want Type=1?
+    if (Config == EIP201_CONFIG_FALLING_EDGE ||
+        Config == EIP201_CONFIG_RISING_EDGE)
+    {
+        NewType = Sources;
+    }
+
+    // do we want Pol=1?
+    if (Config == EIP201_CONFIG_ACTIVE_HIGH ||
+        Config == EIP201_CONFIG_RISING_EDGE)
+    {
+        NewPol = Sources;
+    }
+
+    if (Sources)
+    {
+        // modify polarity register
+        rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, &Value);
+        if (rc) return rc;
+        Value &= ~Sources;
+        Value |= NewPol;
+        rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, Value);
+        if (rc) return rc;
+
+        // modify type register
+        rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, &Value);
+        if (rc) return rc;
+        Value &= ~Sources;
+        Value |= NewType;
+        rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, Value);
+        if (rc) return rc;
+    }
+
+    return EIP201_STATUS_SUCCESS;
+}
+#endif /* EIP201_REMOVE_CONFIG_CHANGE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Config_Read
+ */
+#ifndef EIP201_REMOVE_CONFIG_READ
+
+static const EIP201_Config_t EIP201_Setting2Config[4] =
+{
+    EIP201_CONFIG_ACTIVE_LOW,       // Type=0, Pol=0
+    EIP201_CONFIG_ACTIVE_HIGH,      // Type=0, Pol=1
+    EIP201_CONFIG_FALLING_EDGE,     // Type=1, Pol=0
+    EIP201_CONFIG_RISING_EDGE       // Type=1, Pol=1
+};
+
+EIP201_Config_t
+EIP201_Config_Read(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source)
+{
+    uint32_t Value;
+    unsigned char Setting = 0;
+    int rc = 0;
+
+    rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, &Value);
+    if (rc) return rc;
+    if (Value & Source)
+    {
+        // Type=1, thus edge
+        Setting += 2;
+    }
+
+    EIP201_Read32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, &Value);
+    if (Value & Source)
+    {
+        // Pol=1, this rising edge or active high
+        Setting++;
+    }
+
+    return EIP201_Setting2Config[Setting];
+}
+#endif /* EIP201_REMOVE_CONFIG_READ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_EnableSource
+ *
+ * See header file for function specifications.
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_ENABLESOURCE
+EIP201_Status_t
+EIP201_SourceMask_EnableSource(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources)
+{
+    int rc;
+    EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+    rc = EIP201_Write32(
+            Device,
+            EIP201_REGISTER_OFFSET_ENABLE_SET,
+            Sources);
+
+    return rc;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_ENABLESOURCE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_DisableSource
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_DISABLESOURCE
+EIP201_Status_t
+EIP201_SourceMask_DisableSource(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources)
+{
+    int rc;
+    rc = EIP201_Write32(
+            Device,
+            EIP201_REGISTER_OFFSET_ENABLE_CLR,
+            Sources);
+
+    return rc;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_DISABLESOURCE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_SourceIsEnabled
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED
+bool
+EIP201_SourceMask_SourceIsEnabled(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source)
+{
+    int rc;
+    uint32_t SourceMasks;
+
+    rc =  EIP201_Read32(
+                        Device,
+        EIP201_REGISTER_OFFSET_ENABLE_CTRL, &SourceMasks);
+
+    if (rc) return false;
+    if (SourceMasks & Source)
+        return true;
+
+    return false;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_ReadAll
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_READALL
+EIP201_SourceBitmap_t
+EIP201_SourceMask_ReadAll(
+        Device_Handle_t Device)
+{
+    uint32_t Value;
+    EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, &Value);
+    return Value;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_READALL */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_IsEnabledSourcePending
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING
+bool
+EIP201_SourceStatus_IsEnabledSourcePending(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source)
+{
+    uint32_t Statuses;
+    int rc;
+
+    rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, &Statuses);
+    if (rc) return false;
+
+    if (Statuses & Source)
+        return true;
+
+    return false;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_IsRawSourcePending
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING
+bool
+EIP201_SourceStatus_IsRawSourcePending(
+        Device_Handle_t Device,
+        const EIP201_Source_t Source)
+{
+    uint32_t Statuses;
+    int rc;
+
+    rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, &Statuses);
+    if (rc) return false;
+
+    if (Statuses & Source)
+        return true;
+
+    return false;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllEnabled
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllEnabled(
+        Device_Handle_t Device)
+{
+    uint32_t Value;
+    EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, &Value);
+    return Value;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllRaw
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLRAW
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllRaw(
+        Device_Handle_t Device)
+{
+    uint32_t Value;
+    EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, &Value);
+    return Value;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLRAW */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllEnabledCheck
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllEnabledCheck(
+        Device_Handle_t Device,
+        EIP201_SourceBitmap_t * const Statuses_p)
+{
+    return EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, Statuses_p);
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllRawCheck
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLRAW
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllRawCheck(
+        Device_Handle_t Device,
+        EIP201_SourceBitmap_t * const Statuses_p)
+{
+    return EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, Statuses_p);
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLRAW */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201Lib_Detect
+ *
+ *  Detect the presence of EIP201 hardware.
+ */
+#ifndef EIP201_REMOVE_INITIALIZE
+static EIP201_Status_t
+EIP201Lib_Detect(
+        Device_Handle_t Device)
+{
+    uint32_t Value;
+    int rc;
+
+    rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_VERSION, &Value);
+    if (rc) return rc;
+    Value &= EIP201_SIGNATURE_MASK;
+    if ( Value != EIP201_SIGNATURE)
+        return EIP201_STATUS_UNSUPPORTED_HARDWARE_VERSION;
+
+    // Prevent interrupts going of by disabling them
+    rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, 0);
+    if (rc) return rc;
+
+    // Get the number of interrupt sources
+    rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_OPTIONS, &Value);
+    if (rc) return rc;
+    // lowest 6 bits contain the number of inputs, which should be between 1-32
+    Value &= MASK_6_BITS;
+    if (Value == 0 || Value > 32)
+        return EIP201_STATUS_UNSUPPORTED_HARDWARE_VERSION;
+
+    return EIP201_STATUS_SUCCESS;
+}
+#endif /* EIP201_REMOVE_INITIALIZE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Initialize API
+ *
+ *  See header file for function specification.
+ */
+#ifndef EIP201_REMOVE_INITIALIZE
+EIP201_Status_t
+EIP201_Initialize(
+        Device_Handle_t Device,
+        const EIP201_SourceSettings_t * SettingsArray_p,
+        const unsigned int SettingsCount)
+{
+    EIP201_SourceBitmap_t ActiveLowSources = 0;
+    EIP201_SourceBitmap_t ActiveHighSources = 0;
+    EIP201_SourceBitmap_t FallingEdgeSources = 0;
+    EIP201_SourceBitmap_t RisingEdgeSources = 0;
+    EIP201_SourceBitmap_t EnabledSources = 0;
+    int rc;
+
+    // check presence of EIP201 hardware
+    rc = EIP201Lib_Detect(Device);
+    if (rc) return rc;
+
+    // disable all interrupts and set initial configuration
+    rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, 0);
+    if (rc) return rc;
+    rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, 0);
+    if (rc) return rc;
+    rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, 0);
+    if (rc) return rc;
+
+    // process the setting, if provided
+    if (SettingsArray_p != NULL)
+    {
+        unsigned int i;
+
+        for (i = 0; i < SettingsCount; i++)
+        {
+            // check
+            const EIP201_Source_t Source = SettingsArray_p[i].Source;
+            EIP201_CHECK_IF_IRQ_SUPPORTED(Source);
+
+            // determine polarity
+            switch(SettingsArray_p[i].Config)
+            {
+                case EIP201_CONFIG_ACTIVE_LOW:
+                    ActiveLowSources |= Source;
+                    break;
+
+                case EIP201_CONFIG_ACTIVE_HIGH:
+                    ActiveHighSources |= Source;
+                    break;
+
+                case EIP201_CONFIG_FALLING_EDGE:
+                    FallingEdgeSources |= Source;
+                    break;
+
+                case EIP201_CONFIG_RISING_EDGE:
+                    RisingEdgeSources |= Source;
+                    break;
+
+                default:
+                    // invalid parameter
+                    break;
+            } // switch
+
+            // determine enabled mask
+            if (SettingsArray_p[i].fEnable)
+                EnabledSources |= Source;
+        } // for
+    }
+
+    // program source configuration
+    rc = EIP201_Config_Change(
+            Device,
+            ActiveLowSources,
+            EIP201_CONFIG_ACTIVE_LOW);
+    if (rc) return rc;
+
+    rc = EIP201_Config_Change(
+            Device,
+            ActiveHighSources,
+            EIP201_CONFIG_ACTIVE_HIGH);
+    if (rc) return rc;
+
+    rc = EIP201_Config_Change(
+            Device,
+            FallingEdgeSources,
+            EIP201_CONFIG_FALLING_EDGE);
+    if (rc) return rc;
+
+    rc = EIP201_Config_Change(
+            Device,
+            RisingEdgeSources,
+            EIP201_CONFIG_RISING_EDGE);
+    if (rc) return rc;
+
+    // the configuration change could have triggered the edge-detection logic
+    // so acknowledge all edge-based interrupts immediately
+    {
+        const uint32_t Value = FallingEdgeSources | RisingEdgeSources;
+        rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ACK, Value);
+        if (rc) return rc;
+    }
+
+    // set mask (enable required interrupts)
+    rc = EIP201_SourceMask_EnableSource(Device, EnabledSources);
+
+    return rc;
+}
+#endif /* EIP201_REMOVE_INITIALIZE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Acknowledge
+ *
+ * See header file for function specification.
+ */
+#ifndef EIP201_REMOVE_ACKNOWLEDGE
+EIP201_Status_t
+EIP201_Acknowledge(
+        Device_Handle_t Device,
+        const EIP201_SourceBitmap_t Sources)
+{
+    int rc;
+    EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+    rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ACK, Sources);
+
+    return rc;
+}
+#endif /* EIP201_REMOVE_ACKNOWLEDGE */
+
+/* end of file eip201_sl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c
new file mode 100644
index 0000000..1190450
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c
@@ -0,0 +1,185 @@
+/* eip202_cd_format.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * Command Descriptor Internal interface
+ *
+ * This module contains the EIP-202 Command Descriptor specific functionality
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cd_format.h"
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_cdr.h"                 // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"              // DMAResource_Handle_t
+#include "dmares_rw.h"                 // DMAResource_Write/Read
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Make_ControlWord
+ */
+uint32_t
+EIP202_CD_Make_ControlWord(
+        const uint8_t TokenWordCount,
+        const uint32_t SegmentByteCount,
+        const bool fFirstSegment,
+        const bool fLastSegment,
+        const bool fForceEngine,
+        const uint8_t EngineId)
+{
+    uint32_t Value = 0;
+
+    if(fFirstSegment)
+        Value |= BIT_23;
+
+    if(fLastSegment)
+        Value |= BIT_22;
+
+    Value |= ((((uint32_t)TokenWordCount) & MASK_8_BITS) << 24);
+    Value |= ((((uint32_t)SegmentByteCount) & MASK_16_BITS));
+    if (fForceEngine)
+        Value |= BIT_21 | (((uint32_t)EngineId & MASK_5_BITS) << 16);
+
+    return Value;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Write
+ */
+void
+EIP202_CD_Write(
+        DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const EIP202_ARM_CommandDescriptor_t * const Descr_p,
+        const bool fATP)
+
+{
+    unsigned int InTokenWordOffset;
+
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+    IOToken_Mark_Set(Descr_p->Token_p);
+#endif
+
+#ifdef EIP202_64BIT_DEVICE
+    // Write Control Word
+    DMAResource_Write32(Handle, WordOffset, Descr_p->ControlWord);
+
+    // Lengths greater than 20 bits not supported yet.
+#ifndef EIP202_CDR_OPT1
+    DMAResource_Write32(Handle, WordOffset + 1, 0);
+#endif
+
+    // Write Source Packet Data address
+    DMAResource_Write32(Handle, WordOffset + 2, Descr_p->SrcPacketAddr.Addr);
+    DMAResource_Write32(Handle, WordOffset + 3, Descr_p->SrcPacketAddr.UpperAddr);
+
+    if (fATP)
+    {
+#ifndef EIP202_CDR_OPT2
+        // Write Token Data address
+        DMAResource_Write32(Handle,
+                            WordOffset + 4,
+                            Descr_p->TokenDataAddr.Addr);
+        DMAResource_Write32(Handle,
+                            WordOffset + 5,
+                            Descr_p->TokenDataAddr.UpperAddr);
+#endif
+        InTokenWordOffset = WordOffset + 6;
+    }
+    else
+        InTokenWordOffset = WordOffset + 4;
+#else // EIP202_64BIT_DEVICE
+    // Write Control Word
+    DMAResource_Write32(Handle, WordOffset, Descr_p->ControlWord);
+
+    // Write Source Packet Data address
+    DMAResource_Write32(Handle, WordOffset + 1, Descr_p->SrcPacketAddr.Addr);
+
+    if (fATP)
+    {
+#ifndef EIP202_CDR_OPT2
+        // Write Token Data address
+        DMAResource_Write32(Handle, WordOffset + 2, Descr_p->TokenDataAddr.Addr);
+#endif
+        InTokenWordOffset = WordOffset + 3;
+    }
+    else
+        InTokenWordOffset = WordOffset + 2;
+#endif // !EIP202_64BIT_DEVICE
+
+    // Write Input Token (only for the first segment and if token is available)
+    if (Descr_p->ControlWord & BIT_23 && Descr_p->Token_p)
+    {
+        unsigned int i, offset = InTokenWordOffset;
+
+        // Write Application ID
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+        IOToken_Mark_Set(Descr_p->Token_p);
+#endif
+
+        for (i = 0; i < IOToken_InWordCount_Get(); i++)
+            DMAResource_Write32(Handle, offset + i, Descr_p->Token_p[i]);
+    }
+
+    return;
+}
+
+
+/* end of file eip202_cd_format.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c
new file mode 100644
index 0000000..f7d1527
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c
@@ -0,0 +1,363 @@
+/* eip202_cdr_dscr.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * 1) Descriptor I/O Driver Library API implementation
+ * 2) Internal Command Descriptor interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_cdr.h"
+
+// Internal Command Descriptor interface
+#include "eip202_cdr_dscr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h"         // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h"             // CDR State machine
+#include "eip202_cd_format.h"           // CD Format API
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // types of the DMA resource API
+#include "dmares_rw.h"            // read/write of the DMA resource API.
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_CDR_FillLevel_Finalize
+ *
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_CDR_FillLevel_Finalize(
+        const unsigned int CDWordCount,
+        volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p,
+        unsigned int * const FillLevelDscrCount_p)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+    EIP202_Ring_Error_t rv;
+
+    if(CDWordCount == 0)
+        // CD Ring is empty
+        rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                EIP202_CDR_STATE_INITIALIZED);
+    else if(CDWordCount > 0 &&
+            CDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        // CD Ring is free
+        rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_CDR_STATE_FREE);
+    else if(CDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        // CD Ring is full
+        rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_CDR_STATE_FULL);
+    else
+        rv = EIP202_RING_ILLEGAL_IN_STATE;
+
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+#endif
+
+    // Store actual fill level
+    *FillLevelDscrCount_p = CDWordCount /
+                            (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    // Return actual fill level plus one descriptor to distinguish
+    // ring full from ring empty
+    if(CDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        (*FillLevelDscrCount_p)++;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+  Internal Command Descriptor interface
+  ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_WriteCB
+ */
+int
+EIP202_CDR_WriteCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int WriteIndex,
+        const unsigned int WriteCount,
+        const unsigned int TotalWriteLimit,
+        const void * Descriptors_p,
+        const int DescriptorCount,
+        const unsigned int DescriptorSkipCount)
+{
+    Device_Handle_t Device;
+    unsigned int i, DescOffsetWordCount;
+    unsigned int nWritten = 0;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p =
+                                            CDRIOAREA(CallbackParam1_p);
+    if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+        return -1;
+
+    IDENTIFIER_NOT_USED(CallbackParam2);
+    IDENTIFIER_NOT_USED(DescriptorCount);
+    IDENTIFIER_NOT_USED(TotalWriteLimit);
+
+    Device = TrueIOArea_p->Device;
+
+    DescOffsetWordCount = (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    // Write descriptors to CDR
+    for(i = WriteIndex; i < WriteIndex + WriteCount; i++)
+    {
+        EIP202_CD_Write(
+            TrueIOArea_p->RingHandle,
+            i * DescOffsetWordCount,
+            ((const EIP202_ARM_CommandDescriptor_t *)Descriptors_p) +
+                                            DescriptorSkipCount + nWritten,
+            TrueIOArea_p->fATP);
+
+        nWritten++;
+    }
+
+    if (nWritten > 0)
+    {
+        // Call PreDMA to prepared descriptors in Ring DMA buffer for handover
+        // to the Device (the EIP-202 DMA Master)
+        DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+                           WriteIndex * DescOffsetWordCount *
+                             (unsigned int)sizeof(uint32_t),
+                           nWritten * DescOffsetWordCount *
+                             (unsigned int)sizeof(uint32_t));
+
+        // CDS point: hand over written Command Descriptors to the Device
+        EIP202_CDR_COUNT_WR(Device,
+                            (uint16_t)(nWritten * DescOffsetWordCount),
+                            false);
+    }
+
+    return (int) nWritten;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_ReadCB
+ */
+int
+EIP202_CDR_ReadCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int ReadIndex,
+        const unsigned int ReadLimit,
+        void * Descriptors_p,
+        const unsigned int DescriptorSkipCount)
+{
+    IDENTIFIER_NOT_USED(CallbackParam1_p);
+    IDENTIFIER_NOT_USED(CallbackParam2);
+    IDENTIFIER_NOT_USED(ReadIndex);
+    IDENTIFIER_NOT_USED(ReadLimit);
+    IDENTIFIER_NOT_USED(Descriptors_p);
+    IDENTIFIER_NOT_USED(DescriptorSkipCount);
+
+    // Not used for CDR
+
+    return -1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_StatusCB
+ */
+int
+EIP202_CDR_StatusCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        int * const DeviceReadPos_p)
+{
+    IDENTIFIER_NOT_USED(CallbackParam1_p);
+    IDENTIFIER_NOT_USED(CallbackParam2);
+
+    *DeviceReadPos_p = -1;  // not used
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+  Descriptor I/O Driver Library API implementation
+  ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    Device_Handle_t Device;
+    unsigned int CDWordCount;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    Device = TrueIOArea_p->Device;
+
+    {
+        uint32_t Value32;
+
+        EIP202_CDR_COUNT_RD(Device, &Value32);
+
+        TrueIOArea_p->CountRD       = Value32;
+        TrueIOArea_p->fValidCountRD = true;
+
+        CDWordCount = (unsigned int)Value32;
+    }
+
+    return EIP202Lib_CDR_FillLevel_Finalize(CDWordCount,
+                                            TrueIOArea_p,
+                                            FillLevelDscrCount_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Write_ControlWord
+ */
+uint32_t
+EIP202_CDR_Write_ControlWord(
+        const EIP202_CDR_Control_t * const  CommandCtrl_p)
+{
+    return EIP202_CD_Make_ControlWord(CommandCtrl_p->TokenWordCount,
+                                     CommandCtrl_p->SegmentByteCount,
+                                     CommandCtrl_p->fFirstSegment,
+                                     CommandCtrl_p->fLastSegment,
+                                     CommandCtrl_p->fForceEngine,
+                                     CommandCtrl_p->EngineId);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Descriptor_Put
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Descriptor_Put(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const EIP202_ARM_CommandDescriptor_t * CommandDscr_p,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrDoneCount_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    Device_Handle_t Device;
+    int res;
+    unsigned int CDWordCount, CDFreeCount, CDNewRequestedCount;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(CommandDscr_p);
+    EIP202_RING_CHECK_POINTER(DscrDoneCount_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    Device = TrueIOArea_p->Device;
+
+    // Check how many descriptors can be put
+    {
+        uint32_t Value32;
+
+        if (TrueIOArea_p->fValidCountRD)
+        {
+            Value32 = TrueIOArea_p->CountRD;
+            TrueIOArea_p->fValidCountRD = false;
+        }
+        else
+        {
+            EIP202_CDR_COUNT_RD(Device, &Value32);
+            TrueIOArea_p->CountRD = Value32;
+        }
+
+        CDWordCount = (unsigned int)Value32;
+    }
+
+    // Check if CDR is full
+    if(CDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+    {
+        // CD Ring is full
+        *FillLevelDscrCount_p = CDWordCount /
+                            (unsigned int)TrueIOArea_p->DescOffsWordCount;
+        *DscrDoneCount_p = 0;
+
+        return EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_CDR_STATE_FULL);
+    }
+
+    CDFreeCount =
+            ((unsigned int)TrueIOArea_p->RingSizeWordCount - CDWordCount) /
+                    (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    CDNewRequestedCount = MIN(CDFreeCount, DscrRequestedCount);
+
+    // Put command descriptors to CDR
+    res = RingHelper_Put((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+                         CommandDscr_p,
+                         (int)CDNewRequestedCount);
+    if(res >= 0)
+        *DscrDoneCount_p = (unsigned int)res;
+    else
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Increase the fill level by the number of successfully put descriptors
+    CDWordCount += ((unsigned int)res *
+                         (unsigned int)TrueIOArea_p->DescOffsWordCount);
+
+    return EIP202Lib_CDR_FillLevel_Finalize(CDWordCount,
+                                           TrueIOArea_p,
+                                           FillLevelDscrCount_p);
+}
+
+
+/* end of file eip202_cdr_dscr.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c
new file mode 100644
index 0000000..07e8481
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c
@@ -0,0 +1,172 @@
+/* eip202_cdr_event.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Event Management API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h"         // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h"             // CDR State machine
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Status_Get
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Status_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_CDR_Status_t * const Status_p)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(Status_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202_CDR_STAT_RD(Device,
+                       &Status_p->fDMAError,
+                       &Status_p->fTresholdInt,
+                       &Status_p->fError,
+                       &Status_p->fOUFlowError,
+                       &Status_p->fTimeoutInt,
+                       &Status_p->CDFIFOWordCount);
+
+    EIP202_CDR_COUNT_RD(Device, &Status_p->CDPrepWordCount);
+    EIP202_CDR_PROC_COUNT_RD(Device,
+                             &Status_p->CDProcWordCount,
+                             &Status_p->CDProcPktWordCount);
+
+    // Transit to a new state
+    if(Status_p->fDMAError)
+        rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_CDR_STATE_FATAL_ERROR);
+    else
+        // Remain in the current state
+        rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                                 (EIP202_CDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_Enable
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_Enable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const unsigned int ThresholdDscrCount,
+        const unsigned int Timeout)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202_CDR_THRESH_WR(Device,
+                         (uint32_t)ThresholdDscrCount *
+                               TrueIOArea_p->DescOffsWordCount,
+                         (uint8_t)Timeout);
+
+    // Remain in the current state
+    rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                             (EIP202_CDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_ClearAndDisable
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_ClearAndDisable(
+        EIP202_Ring_IOArea_t * const IOArea_p)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    // Disable timeout interrupt and stop timeout counter for
+    // reducing power consumption
+    EIP202_CDR_THRESH_DEFAULT_WR(Device);
+
+    // Clear all CDR interrupts
+    EIP202_CDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+    // Remain in the current state
+    rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                             (EIP202_CDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_cdr_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c
new file mode 100644
index 0000000..dda97e8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c
@@ -0,0 +1,174 @@
+/* eip202_cdr_fsm.c
+ *
+ * EIP-202 Ring Control Driver Library API
+ * State Machine Internal Interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"              // IDENTIFIER_NOT_USED
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h"        // EIP202_Ring_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_State_Set
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_State_Set(
+        volatile EIP202_CDR_State_t * const CurrentState,
+        const EIP202_CDR_State_t NewState)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+    switch(*CurrentState)
+    {
+        case EIP202_CDR_STATE_UNKNOWN:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+         case EIP202_CDR_STATE_UNINITIALIZED:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_INITIALIZED:
+                   *CurrentState = NewState;
+                   break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_CDR_STATE_INITIALIZED:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_CDR_STATE_FREE:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_CDR_STATE_FULL:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_CDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_CDR_STATE_FATAL_ERROR:
+            switch(NewState)
+            {
+                case EIP202_CDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        default:
+            return EIP202_RING_ILLEGAL_IN_STATE;
+    }
+#else
+    IDENTIFIER_NOT_USED(CurrentState);
+    IDENTIFIER_NOT_USED(NewState);
+#endif // EIP202_RING_DEBUG_FSM
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_cdr_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c
new file mode 100644
index 0000000..4b010f9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c
@@ -0,0 +1,403 @@
+/* eip202_cdr_init.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Init/Reset API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h"          // EIP202_Ring_* types
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h"          // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h"             // CDR State machine
+#include "eip202_cdr_dscr.h"            // RingHelper callbacks
+#include "eip202_cd_format.h"           // EIP-202 Command Descriptor
+
+// RingHelper API
+#include "ringhelper.h"                // RingHelper_Init
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"              // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // types of the DMA resource API
+#include "dmares_rw.h"            // read/write of the DMA resource API.
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"
+
+// Standard IOToken API
+#include "iotoken.h"                   // IOToken_InWordCount_Get()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_Detect
+ *
+ * Checks the presence of EIP-202 HIA hardware. Returns true when found.
+ */
+static bool
+EIP202Lib_CDR_Detect(
+        const Device_Handle_t Device)
+{
+    uint32_t Value;
+
+    // read-write test one of the registers
+
+    // Set MASK_31_BITS bits of the EIP202_CDR_RING_BASE_ADDR_LO register
+    EIP202_CDR_Write32(Device,
+                       EIP202_CDR_RING_BASE_ADDR_LO,
+                       MASK_31_BITS );
+
+    Value = EIP202_CDR_Read32(Device, EIP202_CDR_RING_BASE_ADDR_LO);
+    if ((Value & MASK_31_BITS) != MASK_31_BITS)
+        return false;
+
+    // Clear MASK_31_BITS bits of the EIP202_CDR_RING_BASE_ADDR_LO register
+    EIP202_CDR_Write32(Device, EIP202_CDR_RING_BASE_ADDR_LO, 0);
+    Value = EIP202_CDR_Read32(Device, EIP202_CDR_RING_BASE_ADDR_LO);
+    if ((Value & MASK_31_BITS) != 0)
+       return false;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_CDR_ClearAllDescriptors
+ *
+ * Clear all descriptors
+ */
+static inline void
+EIP202Lib_CDR_ClearAllDescriptors(
+        DMAResource_Handle_t Handle,
+        const uint32_t DescriptorSpacingWordCount,
+        const uint32_t DescriptorSizeWordCount,
+        const uint32_t NumberOfDescriptors)
+{
+    unsigned int i, j;
+
+    for(i = 0; i < NumberOfDescriptors; i++)
+        for(j = 0; j < DescriptorSizeWordCount; j++)
+            DMAResource_Write32(Handle, i * DescriptorSpacingWordCount + j, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Init
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Init(
+        EIP202_Ring_IOArea_t * IOArea_p,
+        const Device_Handle_t Device,
+        const EIP202_CDR_Settings_t * const CDRSettings_p)
+{
+    uint16_t CDFIFOWordCount;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    // Initialize the IO Area
+    TrueIOArea_p->fValidCountRD = false;
+    TrueIOArea_p->Device = Device;
+    TrueIOArea_p->State = (unsigned int)EIP202_CDR_STATE_UNINITIALIZED;
+
+    // Check if the CPU integer size is enough to store 32-bit value
+    if(sizeof(unsigned int) < sizeof(uint32_t))
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    // Detect presence of EIP-202 CDR hardware
+    if(!EIP202Lib_CDR_Detect(Device))
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    if(CDRSettings_p->fATPtoToken)
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    // Extension of 32-bit pointers to 64-bit addresses not supported.
+    if(CDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_EXT_ADDR)
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    if(CDRSettings_p->Params.DscrOffsWordCount == 0 ||
+       CDRSettings_p->Params.DscrOffsWordCount <
+       CDRSettings_p->Params.DscrSizeWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Ring size cannot be smaller than one descriptor size or
+    // larger than 4194303 (16MB / 4 - 1), in 32-bit words
+    if(CDRSettings_p->Params.RingSizeWordCount <
+       CDRSettings_p->Params.DscrOffsWordCount ||
+       CDRSettings_p->Params.RingSizeWordCount > 4194303)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Read Command Descriptor FIFO size (in 32-bit words)
+    EIP202_CDR_STAT_FIFO_SIZE_RD(Device, &CDFIFOWordCount);
+
+    if(CDRSettings_p->Params.DscrSizeWordCount >
+             EIP202_CD_CTRL_DATA_MAX_WORD_COUNT + IOToken_InWordCount_Get() ||
+       CDRSettings_p->Params.DscrSizeWordCount > CDFIFOWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if(CDRSettings_p->Params.DscrFetchSizeWordCount > CDFIFOWordCount ||
+       CDRSettings_p->Params.DscrThresholdWordCount > CDFIFOWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if(CDRSettings_p->Params.DscrFetchSizeWordCount %
+                            CDRSettings_p->Params.DscrOffsWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if( CDRSettings_p->Params.IntThresholdDscrCount >
+        CDRSettings_p->Params.RingSizeWordCount )
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Configure the Ring Helper
+    TrueIOArea_p->RingHelperCallbacks.WriteFunc_p = &EIP202_CDR_WriteCB;
+    TrueIOArea_p->RingHelperCallbacks.ReadFunc_p = &EIP202_CDR_ReadCB;
+    TrueIOArea_p->RingHelperCallbacks.StatusFunc_p = &EIP202_CDR_StatusCB;
+    TrueIOArea_p->RingHelperCallbacks.CallbackParam1_p = IOArea_p;
+    TrueIOArea_p->RingHelperCallbacks.CallbackParam2 = 0;
+    TrueIOArea_p->RingHandle = CDRSettings_p->Params.RingDMA_Handle;
+    TrueIOArea_p->DescOffsWordCount = CDRSettings_p->Params.DscrOffsWordCount;
+    TrueIOArea_p->RingSizeWordCount = CDRSettings_p->Params.RingSizeWordCount;
+    TrueIOArea_p->fATP = CDRSettings_p->fATP;
+
+    // Initialize one RingHelper instance for one CDR instance
+    if( RingHelper_Init(
+         (volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+         (volatile RingHelper_CallbackInterface_t*)&TrueIOArea_p->RingHelperCallbacks,
+         true, // Separate CDR ring
+         (unsigned int)(CDRSettings_p->Params.RingSizeWordCount /
+             CDRSettings_p->Params.DscrOffsWordCount),
+         (unsigned int)(CDRSettings_p->Params.RingSizeWordCount /
+                        CDRSettings_p->Params.DscrOffsWordCount)) < 0)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Transit to a new state
+    rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                             EIP202_CDR_STATE_INITIALIZED);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    // Prepare the CDR DMA buffer
+    // Initialize all descriptors with zero for CDR
+    EIP202Lib_CDR_ClearAllDescriptors(
+            TrueIOArea_p->RingHandle,
+            CDRSettings_p->Params.DscrOffsWordCount,
+            CDRSettings_p->Params.DscrSizeWordCount,
+            CDRSettings_p->Params.RingSizeWordCount /
+                 CDRSettings_p->Params.DscrOffsWordCount);
+
+    // Call PreDMA to make sure engine sees it
+    DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+                       0,
+                       (unsigned int)(TrueIOArea_p->RingSizeWordCount*4));
+
+    EIP202_CDR_RING_BASE_ADDR_LO_WR(
+                       Device,
+                       CDRSettings_p->Params.RingDMA_Address.Addr);
+
+    EIP202_CDR_RING_BASE_ADDR_HI_WR(
+                       Device,
+                       CDRSettings_p->Params.RingDMA_Address.UpperAddr);
+
+    EIP202_CDR_RING_SIZE_WR(
+                       Device,
+                       CDRSettings_p->Params.RingSizeWordCount);
+
+    EIP202_CDR_DESC_SIZE_WR(
+                       Device,
+                       CDRSettings_p->Params.DscrSizeWordCount,
+                       CDRSettings_p->Params.DscrOffsWordCount,
+                       CDRSettings_p->fATPtoToken,
+                       CDRSettings_p->fATP,
+                       CDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_DSCR_PTR);
+
+    EIP202_CDR_CFG_WR(
+                       Device,
+                       CDRSettings_p->Params.DscrFetchSizeWordCount,
+                       CDRSettings_p->Params.DscrThresholdWordCount);
+
+    EIP202_CDR_DMA_CFG_WR(
+                       Device,
+                       (uint8_t)CDRSettings_p->Params.ByteSwap_Descriptor_Mask,
+                       (uint8_t)CDRSettings_p->Params.ByteSwap_Packet_Mask,
+                       (uint8_t)CDRSettings_p->Params.ByteSwap_Token_Mask,
+                       // Bufferability control
+                       true,  // Buffer Ownership Word DMA writes
+                       EIP202_RING_CD_WR_CACHE_CTRL, // Write cache type control
+                       EIP202_RING_CD_RD_CACHE_CTRL, // Read cache type control
+                       EIP202_RING_CD_PROT_VALUE,
+                       EIP202_RING_DATA_PROT_VALUE,
+                       EIP202_RING_ACD_PROT_VALUE);
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Reset
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Reset(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    // Initialize the IO Area
+    memset((void*)IOArea_p, 0, sizeof(*TrueIOArea_p));
+    TrueIOArea_p->Device = Device;
+    TrueIOArea_p->State = (unsigned int)EIP202_CDR_STATE_UNKNOWN;
+
+    // Transit to a new state
+    rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+                             EIP202_CDR_STATE_UNINITIALIZED);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    // Clear CDR count
+    EIP202_CDR_COUNT_WR(Device, 0, true);
+
+    // Re-init CDR
+    EIP202_CDR_POINTER_DEFAULT_WR(Device);
+
+    // Restore default register values
+    EIP202_CDR_RING_BASE_ADDR_LO_DEFAULT_WR(Device);
+    EIP202_CDR_RING_BASE_ADDR_HI_DEFAULT_WR(Device);
+    EIP202_CDR_RING_SIZE_DEFAULT_WR(Device);
+    EIP202_CDR_DESC_SIZE_DEFAULT_WR(Device);
+    EIP202_CDR_CFG_DEFAULT_WR(Device);
+    EIP202_CDR_DMA_CFG_DEFAULT_WR(Device);
+
+    // Clear and disable all CDR interrupts
+    EIP202_CDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Options_Get
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Options_Get(
+        const Device_Handle_t Device,
+        EIP202_Ring_Options_t * const Options_p)
+{
+    uint32_t Rev;
+
+    EIP202_RING_CHECK_POINTER(Options_p);
+
+    // Note: thie register does not exist in all versions of the device.
+    //       If it exists, the options register is also available.
+    Rev = EIP202_CDR_Read32(Device, EIP202_CDR_VERSION);
+    if ( !EIP202_CDR_REV_SIGNATURE_MATCH((uint16_t)Rev))
+    {
+        // No local CDR version and options registers available,
+        // function not supported
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+    }
+
+    EIP202_CDR_OPTIONS_RD(Device,
+                          &Options_p->NofRings,
+                          &Options_p->NofPes,
+                          &Options_p->fExpPlf,
+                          &Options_p->CF_Size,
+                          &Options_p->RF_Size,
+                          &Options_p->HostIfc,
+                          &Options_p->DMA_Len,
+                          &Options_p->HDW,
+                          &Options_p->TgtAlign,
+                          &Options_p->fAddr64);
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Dump
+ *
+ */
+void
+EIP202_CDR_Dump(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RingAdmin_t * const RingAdmin_p)
+{
+    EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+                            (EIP202_RDR_True_IOArea_t * const)IOArea_p;
+
+    if(!TrueIOArea_p)
+        return;
+
+    if(!RingAdmin_p)
+        return;
+
+    RingAdmin_p->IN_Size           = TrueIOArea_p->RingHelper.IN_Size;
+    RingAdmin_p->IN_Tail           = TrueIOArea_p->RingHelper.IN_Tail;
+    RingAdmin_p->OUT_Size          = TrueIOArea_p->RingHelper.OUT_Size;
+    RingAdmin_p->OUT_Head          = TrueIOArea_p->RingHelper.OUT_Head;
+
+    RingAdmin_p->fSeparate         = TrueIOArea_p->RingHelper.fSeparate;
+
+    RingAdmin_p->DescOffsWordCount = TrueIOArea_p->DescOffsWordCount;
+    RingAdmin_p->RingSizeWordCount = TrueIOArea_p->RingSizeWordCount;
+}
+
+
+/* end of file eip202_cdr_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c
new file mode 100644
index 0000000..7a0006d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c
@@ -0,0 +1,457 @@
+/* eip202_global_init.c
+ *
+ * EIP-202 Global Control Driver Library
+ * Initialization Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                   // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+#include "eip202_global_level0.h"   // EIP-202 Level 0 macros
+
+// EIP97_Interfaces_Get
+#include "eip97_global_internal.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Detect
+ */
+bool
+EIP202_Global_Detect(
+        const Device_Handle_t Device)
+{
+    uint32_t Value;
+
+    Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+    if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+        return false;
+
+    return true;
+}
+
+
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_HWRevision_Get
+ */
+void
+EIP202_Global_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP202_Capabilities_t * const Capabilities_p)
+{
+    EIP202_EIP_REV_RD(Device,
+                      &Capabilities_p->EipNumber,
+                      &Capabilities_p->ComplmtEipNumber,
+                      &Capabilities_p->HWPatchLevel,
+                      &Capabilities_p->MinHWRevision,
+                      &Capabilities_p->MajHWRevision);
+
+    EIP202_OPTIONS_RD(Device,
+                      &Capabilities_p->NofRings,
+                      &Capabilities_p->NofPes,
+                      &Capabilities_p->fExpPlf,
+                      &Capabilities_p->CF_Size,
+                      &Capabilities_p->RF_Size,
+                      &Capabilities_p->HostIfc,
+                      &Capabilities_p->DMA_Len,
+                      &Capabilities_p->HDW,
+                      &Capabilities_p->TgtAlign,
+                      &Capabilities_p->fAddr64);
+
+    EIP202_OPTIONS2_RD(Device,
+                       &Capabilities_p->NofLA_Ifs,
+                       &Capabilities_p->NofIN_Ifs,
+                       &Capabilities_p->NofAXI_WrChs,
+                       &Capabilities_p->NofAXI_RdClusters,
+                       &Capabilities_p->NofAXI_RdCPC);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Endianness_Slave_Configure
+ *
+ * Configure Endianness Conversion method
+ * for the EIP-202 slave (MMIO) interface
+ *
+ */
+bool
+EIP202_Global_Endianness_Slave_Configure(
+        const Device_Handle_t Device)
+{
+#ifdef EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+    uint32_t Value;
+
+    // Read and check the revision register
+    Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+    if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+    {
+        // No match, try to enable the Slave interface byte swap
+        // Must be done via EIP-202 HIA GLobal
+        EIP202_MST_CTRL_BYTE_SWAP_UPDATE(Device, true);
+
+        // Read and check the revision register again
+        Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+        if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+            // Bail out if still not OK
+            return false;
+    }
+
+    return true;
+#else
+    IDENTIFIER_NOT_USED(Device);
+    return true;
+#endif // EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Init
+ */
+void
+EIP202_Global_Init(
+        const Device_Handle_t Device,
+        unsigned int NofPE,
+        unsigned int NofLA,
+        uint8_t ipbuf_min,
+        uint8_t ipbuf_max,
+        uint8_t itbuf_min,
+        uint8_t itbuf_max,
+        uint8_t opbuf_min,
+        uint8_t opbuf_max)
+{
+    unsigned int i;
+    uint8_t BufferCtrl;
+    unsigned int NofPEs,NofRings,NofLAs,NofIN,DFEDSEOffset;
+    EIP97_Interfaces_Get(&NofPEs,&NofRings,&NofLAs,&NofIN);
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+    // Configure EIP-202 HIA Global
+    EIP202_MST_CTRL_BUS_BURST_SIZE_UPDATE(Device,
+                                          EIP97_GLOBAL_BUS_BURST_SIZE,
+                                          EIP97_GLOBAL_RX_BUS_BURST_SIZE);
+    EIP202_MST_CTRL_BUS_TIMEOUT_UPDATE(Device,
+                                       EIP97_GLOBAL_TIMEOUT_VALUE);
+    if (NofLA)
+        // User-configured value
+        BufferCtrl = EIP97_GLOBAL_DSE_BUFFER_CTRL;
+    else
+        // Default register reset value
+        BufferCtrl = (uint8_t)EIP202_DSE_BUFFER_CTRL;
+
+    for (i = 0; i < NofPE; i++)
+    {
+        // Configure EIP-202 HIA DFE Global
+        EIP202_DFE_CFG_WR(Device,
+                          DFEDSEOffset,
+                          i,
+                          ipbuf_min,
+                          EIP97_GLOBAL_DFE_DATA_CACHE_CTRL,
+                          ipbuf_max,
+                          itbuf_min,
+                          EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL,
+                          itbuf_max,
+                          (EIP97_GLOBAL_DFE_ADV_THRESH_MODE_FLAG == 1),
+                          (EIP97_GLOBAL_DFE_AGGRESSIVE_DMA_FLAG == 1));
+
+        // Configure EIP-202 HIA DSE Global
+        EIP202_DSE_CFG_WR(Device,
+                          DFEDSEOffset,
+                          i,
+                          opbuf_min,
+                          EIP97_GLOBAL_DSE_DATA_CACHE_CTRL,
+                          opbuf_max,
+                          BufferCtrl,
+                          (EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG == 1),
+                          (EIP97_GLOBAL_DSE_AGGRESSIVE_DMA_FLAG == 1));
+
+    }
+
+    // Configure HIA Look-aside FIFO
+    EIP202_LASIDE_BASE_ADDR_LO_WR(Device,
+                                  EIP202_LASIDE_DSCR_BYTE_SWAP_METHOD);
+
+    for (i = EIP97_GLOBAL_LAFIFO_RING_ID;
+         i < NofLAs +
+             EIP97_GLOBAL_LAFIFO_RING_ID;
+         i++)
+    {
+        EIP202_LASIDE_SLAVE_CTRL_WR(Device,
+                                    i,
+                                    EIP202_LASIDE_IN_PKT_BYTE_SWAP_METHOD,
+                                    EIP202_LASIDE_IN_PKT_PROTO,
+                                    EIP202_LASIDE_TOKEN_BYTE_SWAP_METHOD,
+                                    EIP202_LASIDE_TOKEN_PROTO,
+                                    true); // Clear cmd descriptor error
+
+        EIP202_LASIDE_MASTER_CTRL_WR(Device,
+                                     i,
+                                     EIP202_LASIDE_OUT_PKT_BYTE_SWAP_METHOD,
+                                     EIP202_LASIDE_OUT_PKT_PROTO,
+                                     true); // Clear res descriptor error
+    }
+    // Configure HIA Inline FIFO
+    for (i = 0; i < NofIN; i++)
+        EIP202_INLINE_CTRL_WR(Device,
+                              i,
+                              EIP202_INLINE_IN_PKT_BYTE_SWAP_METHOD,
+                              false, // Clear protocol error
+                              EIP202_INLINE_OUT_PKT_BYTE_SWAP_METHOD,
+                              opbuf_min,
+                              opbuf_max,
+                              EIP202_INLINE_BURST_SIZE,
+                              EIP202_INLINE_FORCE_INORDER);
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset
+ */
+bool
+EIP202_Global_Reset(
+        const Device_Handle_t Device,
+        const unsigned int NofPE)
+{
+    unsigned int i;
+    unsigned int DFEDSEOffset;
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+    // Restore the EIP-202 default configuration
+    // Resets DFE thread and clears ring assignment
+    for (i = 0; i < NofPE; i++)
+        EIP202_DFE_TRD_CTRL_WR(Device, DFEDSEOffset, i, 0, false, true);
+
+    // HIA DFE defaults
+    for (i = 0; i < NofPE; i++)
+        EIP202_DFE_CFG_DEFAULT_WR(Device, DFEDSEOffset, i);
+
+#ifndef EIP202_RA_DISABLE
+    EIP202_RA_PRIO_0_DEFAULT_WR(Device);
+    EIP202_RA_PRIO_1_DEFAULT_WR(Device);
+    EIP202_RA_PRIO_2_DEFAULT_WR(Device);
+    EIP202_RA_PRIO_3_DEFAULT_WR(Device);
+
+    // Resets ring assignment
+    for (i = 0; i < NofPE; i++)
+        EIP202_RA_PE_CTRL_WR(Device, i, 0, false, true);
+#endif // #ifndef EIP202_RA_DISABLE
+
+    // Resets DSE thread and clears ring assignment
+    for (i = 0; i < NofPE; i++)
+        EIP202_DSE_TRD_CTRL_WR(Device, DFEDSEOffset, i, 0, false, true);
+
+    // HIA DSE defaults
+    for (i = 0; i < NofPE; i++)
+        EIP202_DSE_CFG_DEFAULT_WR(Device, DFEDSEOffset, i);
+
+
+    // HIA LASIDE defaults
+    EIP202_LASIDE_BASE_ADDR_LO_DEFAULT_WR(Device);
+    EIP202_LASIDE_BASE_ADDR_HI_DEFAULT_WR(Device);
+    for (i = EIP97_GLOBAL_LAFIFO_RING_ID;
+         i < EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE + EIP97_GLOBAL_LAFIFO_RING_ID;
+         i++)
+    {
+        EIP202_LASIDE_MASTER_CTRL_DEFAULT_WR(Device, i);
+        EIP202_LASIDE_SLAVE_CTRL_DEFAULT_WR(Device, i);
+    }
+
+    // HIA INLINE defaults
+    for (i = 0; i < NofPE; i++)
+        EIP202_INLINE_CTRL_DEFAULT_WR(Device, i);
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset_IsDone
+ */
+bool
+EIP202_Global_Reset_IsDone(
+        const Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    uint8_t RingId;
+    unsigned int DFEDSEOffset;
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+    // Check for completion of all DMA transfers
+    EIP202_DFE_TRD_STAT_RINGID_RD(Device, DFEDSEOffset, PEnr, &RingId);
+    if(RingId == EIP202_DFE_TRD_REG_STAT_IDLE)
+    {
+        EIP202_DSE_TRD_STAT_RINGID_RD(Device, DFEDSEOffset, PEnr, &RingId);
+        if(RingId == EIP202_DFE_TRD_REG_STAT_IDLE)
+        {
+            // Take DFE thread out of reset
+            EIP202_DFE_TRD_CTRL_DEFAULT_WR(Device, DFEDSEOffset, PEnr);
+
+            // Take DSE thread out of reset
+            EIP202_DSE_TRD_CTRL_DEFAULT_WR(Device, DFEDSEOffset, PEnr);
+
+            // Do not restore the EIP-202 Master Control default configuration
+            // so this will not change the endianness conversion configuration
+            // for the Slave interface
+        }
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Configure
+ */
+void
+EIP202_Global_Configure(
+        const Device_Handle_t Device,
+        const unsigned int PE_Number,
+        const EIP202_Global_Ring_PE_Map_t * const RingPEMap_p)
+{
+    unsigned int DFEDSEOffset;
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+    // Disable EIP-202 HIA DFE thread(s)
+    EIP202_DFE_TRD_CTRL_WR(Device,
+                           DFEDSEOffset,
+                           PE_Number,   // Thread Nr
+                           0,
+                           false,       // Disable thread
+                           false);      // Do not reset thread
+
+    // Disable EIP-202 HIA DSE thread(s)
+    EIP202_DSE_TRD_CTRL_WR(Device,
+                           DFEDSEOffset,
+                           PE_Number,   // Thread Nr
+                           0,
+                           false,       // Disable thread
+                           false);      // Do not reset thread
+
+#ifndef EIP202_RA_DISABLE
+    // Configure the HIA Ring Arbiter
+    EIP202_RA_PRIO_0_WR(
+            Device,
+            (RingPEMap_p->RingPrio_Mask & BIT_0) == 0 ? false : true,
+            (uint8_t)(RingPEMap_p->RingSlots0 & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_1) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 4) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_2) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 8) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_3) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 12) & MASK_4_BITS));
+
+    EIP202_RA_PRIO_1_WR(
+            Device,
+            (RingPEMap_p->RingPrio_Mask & BIT_4) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 16) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_5) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 20) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_6) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 24) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_7) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots0 >> 28) & MASK_4_BITS));
+
+    EIP202_RA_PRIO_2_WR(
+            Device,
+            (RingPEMap_p->RingPrio_Mask & BIT_8) == 0 ? false : true,
+            (uint8_t)(RingPEMap_p->RingSlots1 & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_9) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 4) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_10) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 8) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_11) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 12) & MASK_4_BITS));
+
+    EIP202_RA_PRIO_3_WR(
+            Device,
+            (RingPEMap_p->RingPrio_Mask & BIT_12) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 16) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_13) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 20) & MASK_4_BITS),
+            (RingPEMap_p->RingPrio_Mask & BIT_14) == 0 ? false : true,
+            (uint8_t)((RingPEMap_p->RingSlots1 >> 24) & MASK_4_BITS));
+
+    // Ring assignment in the Ring Arbiter
+    EIP202_RA_PE_CTRL_WR(Device,
+                         PE_Number,
+                         RingPEMap_p->RingPE_Mask,
+                         true,
+                         false);
+#endif // #ifndef EIP202_RA_DISABLE
+
+    {
+        // Assign Rings to this DFE thread
+        // Enable EIP-202 HIA DFE thread(s)
+        EIP202_DFE_TRD_CTRL_WR(Device,
+                               DFEDSEOffset,
+                               PE_Number,   // Thread Nr
+                               RingPEMap_p->RingPE_Mask,  // Rings to assign
+                               true,        // Enable thread
+                               false);      // Do not reset thread
+
+        // Assign Rings to this DSE thread
+        // Enable EIP-202 HIA DSE thread(s)
+        EIP202_DSE_TRD_CTRL_WR(Device,
+                               DFEDSEOffset,
+                               PE_Number,   // Thread Nr
+                               RingPEMap_p->RingPE_Mask,   // Rings to assign
+                               true,        // Enable thread
+                               false);      // Do not reset thread
+    }
+}
+
+/* end of file eip202_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c
new file mode 100644
index 0000000..d3ce3c6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c
@@ -0,0 +1,313 @@
+/* eip202_rd_format.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * Result Descriptor Internal interface
+ *
+ * This module contains the EIP-202 Result Descriptor specific functionality
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rd_format.h"
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_rdr.h"                 // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"              // DMAResource_Handle_t
+#include "dmares_rw.h"                 // DMAResource_Write/Read
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Make_ControlWord
+ */
+uint32_t
+EIP202_RD_Make_ControlWord(
+        const uint8_t ExpectedResultWordCount,
+        const uint32_t PrepSegmentByteCount,
+        const bool fFirstSegment,
+        const bool fLastSegment)
+{
+    uint32_t Value = 0;
+
+    if(fFirstSegment)
+        Value |= BIT_23;
+
+    if(fLastSegment)
+        Value |= BIT_22;
+
+    Value |= ((((uint32_t)ExpectedResultWordCount) & MASK_8_BITS) << 24);
+    Value |= ((((uint32_t)PrepSegmentByteCount)    & MASK_20_BITS));
+
+    return Value;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Prepared_Write
+ */
+void
+EIP202_Prepared_Write(
+        DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const EIP202_ARM_PreparedDescriptor_t * const Descr_p)
+{
+#ifdef EIP202_64BIT_DEVICE
+    // Write Control Word
+    DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
+
+    // Do not support lengths greater than 20 bit.
+    DMAResource_Write32(Handle, WordOffset + 1, 0);
+
+    // Write Destination Packet Data address
+    DMAResource_Write32(Handle, WordOffset + 2, Descr_p->DstPacketAddr.Addr);
+    DMAResource_Write32(Handle, WordOffset + 3, Descr_p->DstPacketAddr.UpperAddr);
+
+#else
+    // Write Control Word
+    DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
+
+    // Write Destination Packet Data address
+    DMAResource_Write32(Handle, WordOffset + 1, Descr_p->DstPacketAddr.Addr);
+#endif
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ReadDescriptor
+ */
+void
+EIP202_ReadDescriptor(
+        EIP202_ARM_ResultDescriptor_t * const Descr_p,
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const unsigned int DscrOffsWordCount,
+        const unsigned int TokenOffsWordCount,
+        bool * const fLastSegment,
+        bool * const fFirstSegment)
+{
+    unsigned int OutTokenWordOffset;
+
+#ifdef EIP202_64BIT_DEVICE
+    // Word 0 - Control Word
+    Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
+
+    // Word 1 - extended length, not read.
+
+    // Word 2 & 3 - Destination Packet Data Buffer Address
+    Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 2);
+    Descr_p->DstPacketAddr.UpperAddr = DMAResource_Read32(Handle, WordOffset + 3);
+
+    OutTokenWordOffset = WordOffset + TokenOffsWordCount;
+#else // EIP202_64BIT_DEVICE
+    // Word 0 - Control Word
+    Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
+
+    // Word 1 - Destination Packet Data Buffer Address
+    Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 1);
+
+    OutTokenWordOffset = WordOffset + 2;
+#endif // !EIP202_64BIT_DEVICE
+
+    if (Descr_p->Token_p == NULL)
+    {
+        *fLastSegment   = false;
+        *fFirstSegment  = false;
+        return; // Fatal error
+    }
+
+    // Read token data
+    {
+        unsigned int i;
+
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+        for (i = 0; i < IOToken_OutWordCount_Get(); i++)
+            if (i != (unsigned int)IOToken_OutMarkOffset_Get())
+                Descr_p->Token_p[i] = DMAResource_Read32(
+                                          Handle,
+                                          OutTokenWordOffset + i);
+#else
+        for (i = 0; i < IOToken_OutWordCount_Get(); i++)
+            Descr_p->Token_p[i] = DMAResource_Read32(
+                                    Handle,
+                                    OutTokenWordOffset + i);
+#endif
+    }
+
+    // Check if this descriptor is for the last segment
+    if((Descr_p->ProcControlWord & BIT_22) != 0)
+        *fLastSegment = true; // Processed packet
+    else
+        *fLastSegment = false;
+
+    // Check if this descriptor is for the first segment
+    if((Descr_p->ProcControlWord & BIT_23) != 0)
+        *fFirstSegment = true; // New packet descriptor chain detected
+    else
+        *fFirstSegment = false;
+
+    IDENTIFIER_NOT_USED(DscrOffsWordCount);
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ClearDescriptor
+ */
+void
+EIP202_ClearDescriptor(
+        EIP202_ARM_ResultDescriptor_t * const Descr_p,
+        const DMAResource_Handle_t Handle,
+        const unsigned int WordOffset,
+        const unsigned int TokenOffsWordCount,
+        const unsigned int DscrWordCount)
+{
+    IDENTIFIER_NOT_USED(Descr_p);
+
+#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+
+    DMAResource_Write32(Handle, WordOffset + DscrWordCount - 1, 0);
+    IDENTIFIER_NOT_USED(TokenOffsWordCount);
+
+#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
+
+    IDENTIFIER_NOT_USED(DscrWordCount);
+
+    DMAResource_Write32(Handle,
+                        WordOffset + TokenOffsWordCount +
+                                  IOToken_OutMarkOffset_Get(),
+                        0);
+#else
+    IDENTIFIER_NOT_USED(Handle);
+    IDENTIFIER_NOT_USED(WordOffset);
+    IDENTIFIER_NOT_USED(DscrWordCount);
+    IDENTIFIER_NOT_USED(TokenOffsWordCount);
+#endif // !EIP202_RDR_OWNERSHIP_WORD_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_ControlWord
+ */
+void
+EIP202_RD_Read_ControlWord(
+        const uint32_t ControlWord,
+        uint32_t * TokenData_p,
+        EIP202_RDR_Result_Control_t * const RDControl_p,
+        EIP202_RDR_Result_Token_t * const ResToken_p)
+{
+    RDControl_p->ProcSegmentByteCount =  (ControlWord        & MASK_20_BITS);
+    RDControl_p->ProcResultWordCount  = ((ControlWord >> 24) & MASK_8_BITS);
+
+    // Fill in EIP202_RDR_Result_Control_t
+    if((ControlWord & BIT_20) != 0)
+        RDControl_p->fDscrOverflow = true;
+    else
+        RDControl_p->fDscrOverflow = false;
+
+    if((ControlWord & BIT_21) != 0)
+        RDControl_p->fBufferOverflow = true;
+    else
+        RDControl_p->fBufferOverflow = false;
+
+    if((ControlWord & BIT_22) != 0)
+        RDControl_p->fLastSegment = true;
+    else
+        RDControl_p->fLastSegment = false;
+
+    if((ControlWord & BIT_23) != 0)
+        RDControl_p->fFirstSegment = true;
+    else
+        RDControl_p->fFirstSegment = false;
+
+    IDENTIFIER_NOT_USED(TokenData_p);
+    IDENTIFIER_NOT_USED(ResToken_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_BypassData
+ */
+void
+EIP202_RD_Read_BypassData(
+        const uint32_t * BypassData_p,
+        const uint8_t BypassWordCount,
+        EIP202_RDR_BypassData_t * const BD_p)
+{
+    if (BypassWordCount == 1)
+    {
+        BD_p->Fail.ErrorFlags = BypassData_p[0] & MASK_2_BITS;
+    }
+    else if (BypassWordCount == 2)
+    {
+        BD_p->Pass.TOS_TC           = BypassData_p[0] & MASK_8_BITS;
+        BD_p->Pass.fDF              = ((BypassData_p[0] & BIT_8) != 0);
+        BD_p->Pass.NextHeaderOffset = (BypassData_p[0] >> 8) & MASK_16_BITS;
+        BD_p->Pass.HdrProcCtxRef    = BypassData_p[1];
+    }
+    else
+    {
+        IDENTIFIER_NOT_USED(BypassData_p);
+        IDENTIFIER_NOT_USED(BypassWordCount);
+        IDENTIFIER_NOT_USED(BD_p);
+    }
+}
+
+
+/* end of file eip202_rd_format.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c
new file mode 100644
index 0000000..831a486
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c
@@ -0,0 +1,735 @@
+/* eip202_rdr_dscr.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * 1) Descriptor I/O Driver Library API implementation
+ * 2) Internal Result Descriptor interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_rdr.h"
+
+// Internal Result Descriptor interface
+#include "eip202_rdr_dscr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h"         // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h"             // RDR State machine
+#include "eip202_rd_format.h"           // RD Format API
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // types of the DMA resource API
+#include "dmares_rw.h"            // read/write of the DMA resource API.
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-202 HW limit for the number of packets to acknowledge at once
+#define EIP202_RING_MAX_RD_PACKET_COUNT      127
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_Prepared_FillLevel_Get
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_RDR_Prepared_FillLevel_Get(
+        const Device_Handle_t Device,
+        volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
+        unsigned int * const FillLevelDscrCount_p)
+{
+    unsigned int RDWordCount;
+    EIP202_Ring_Error_t rv;
+
+    EIP202_RDR_PREP_COUNT_RD(Device, (uint32_t*)&RDWordCount);
+
+    // Remain in the current state
+    rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                             (EIP202_RDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    *FillLevelDscrCount_p = RDWordCount /
+                            (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    if(RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        (*FillLevelDscrCount_p)++;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_Processed_FillLevel_Finalize
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_RDR_Processed_FillLevel_Finalize(
+        const unsigned int RDWordCount,
+        const unsigned int PktCount,
+        volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
+        unsigned int * const FillLevelDscrCount_p,
+        unsigned int * const FillLevelPktCount_p)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+    EIP202_Ring_Error_t rv;
+
+    if(RDWordCount == 0)
+        // CD Ring is empty
+        rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                EIP202_RDR_STATE_INITIALIZED);
+    else if(RDWordCount > 0 &&
+            RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        // CD Ring is free
+        rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_RDR_STATE_FREE);
+    else if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+        // CD Ring is full
+        rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_RDR_STATE_FULL);
+    else
+        rv = EIP202_RING_ILLEGAL_IN_STATE;
+
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+#endif
+
+    *FillLevelDscrCount_p = RDWordCount /
+                            (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    *FillLevelPktCount_p = PktCount;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+  Internal Result Descriptor interface
+  ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_WriteCB
+ */
+int
+EIP202_RDR_WriteCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int WriteIndex,
+        const unsigned int WriteCount,
+        const unsigned int TotalWriteLimit,
+        const void * Descriptors_p,
+        const int DescriptorCount,
+        const unsigned int DescriptorSkipCount)
+{
+    Device_Handle_t Device;
+    unsigned int i, DescOffsetWordCount;
+    unsigned int nWritten = 0;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+                                            RDRIOAREA(CallbackParam1_p);
+    if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+        return -1;
+
+    IDENTIFIER_NOT_USED(CallbackParam2);
+    IDENTIFIER_NOT_USED(DescriptorCount);
+    IDENTIFIER_NOT_USED(TotalWriteLimit);
+
+    Device = TrueIOArea_p->Device;
+
+    DescOffsetWordCount = (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    // Write descriptors to RDR
+    for(i = WriteIndex; i < WriteIndex + WriteCount; i++)
+    {
+        EIP202_Prepared_Write(
+            TrueIOArea_p->RingHandle,
+            i * DescOffsetWordCount,
+            ((const EIP202_ARM_PreparedDescriptor_t *)Descriptors_p) +
+                    DescriptorSkipCount + nWritten);
+
+        nWritten++;
+    }
+
+    if (nWritten > 0)
+    {
+        // Call PreDMA to prepared descriptors in Ring DMA buffer for handover
+        // to the Device (the EIP-202 DMA Master)
+        DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+                           WriteIndex *
+                              DescOffsetWordCount *
+                               (unsigned int)sizeof(uint32_t),
+                           nWritten *
+                             DescOffsetWordCount *
+                               (unsigned int)sizeof(uint32_t));
+
+        // CDS point: hand over written Prepared Descriptors to the Device
+        EIP202_RDR_PREP_COUNT_WR(Device,
+                                 (uint16_t)(nWritten * DescOffsetWordCount),
+                                 false);
+    }
+
+    return (int)nWritten;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_ReadCB
+ */
+int
+EIP202_RDR_ReadCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        const unsigned int ReadIndex,
+        const unsigned int ReadLimit,
+        void * Descriptors_p,
+        const unsigned int DescriptorSkipCount)
+{
+    Device_Handle_t Device;
+    unsigned int i, DescOffsetWordCount;
+    bool fGotDescriptor, fLastSegment = false, fFirstSegment = false;
+    unsigned int GotDscrCount = 0, GotPktCount = 0;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+                                       RDRIOAREA(CallbackParam1_p);
+
+    if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+        return -1;
+
+    IDENTIFIER_NOT_USED(CallbackParam2);
+
+    Device = TrueIOArea_p->Device;
+
+    DescOffsetWordCount = (unsigned int )TrueIOArea_p->DescOffsWordCount;
+
+    // Read descriptors from RDR
+    for(i = ReadIndex; i < ReadIndex + ReadLimit; i++)
+    {
+        EIP202_ARM_ResultDescriptor_t * CurrentResultDesc_p =
+            ((EIP202_ARM_ResultDescriptor_t *)Descriptors_p) +
+                    DescriptorSkipCount + GotDscrCount;
+
+#define EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE             \
+         (TrueIOArea_p->AcknowledgedRDCount + GotDscrCount >=  \
+              TrueIOArea_p->RDToGetCount)
+
+// This can be true only if the PktRequestedCount parameter in
+// the EIP202_RDR_Descriptor_Get() function is set to a non-zero value
+#define EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE                 \
+         (TrueIOArea_p->PktToGetCount > 0 &&                   \
+          TrueIOArea_p->AcknowledgedPktCount + GotPktCount >=  \
+              TrueIOArea_p->PktToGetCount)
+
+        // Stop reading the descriptors if all the requested
+        // descriptors and packet chains have been read
+        if(EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
+        {
+            if(EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE)
+                break; // for
+        }
+
+        // Call PostDMA before reading descriptors from
+        // the EIP-202 DMA Master
+        DMAResource_PostDMA(TrueIOArea_p->RingHandle,
+                            i * DescOffsetWordCount *
+                              (unsigned int)sizeof(uint32_t),
+                            DescOffsetWordCount *
+                              (unsigned int)sizeof(uint32_t));
+
+        // Check if a processed result descriptor is received
+#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+        {
+            uint32_t OwnershipWord =
+                        DMAResource_Read32(TrueIOArea_p->RingHandle,
+                                           i * DescOffsetWordCount +
+                                                 DescOffsetWordCount - 1);
+            fGotDescriptor =
+                    (OwnershipWord == EIP202_RDR_OWNERSHIP_WORD_PATTERN);
+#ifdef EIP202_RING_BUS_KEEPALIVE_WORKAROUND
+            // Read from the device to solve a keep-alive problem in some
+            // bus environments.
+            Device_Read32(Device,0);
+#endif
+        }
+#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
+        CurrentResultDesc_p->Token_p[IOToken_OutMarkOffset_Get()] =
+                DMAResource_Read32(TrueIOArea_p->RingHandle,
+                                   i * DescOffsetWordCount +
+                                   TrueIOArea_p->TokenOffsetWordCount +
+                                   IOToken_OutMarkOffset_Get());
+        fGotDescriptor = (IOToken_Mark_Check(CurrentResultDesc_p->Token_p) == 0);
+#else
+        fGotDescriptor = true; // according to EIP202_RDR_PROC_COUNT_RD()
+#endif
+
+        if (fGotDescriptor)
+        {
+            // Read Result Descriptor
+            EIP202_ReadDescriptor(CurrentResultDesc_p,
+                                  TrueIOArea_p->RingHandle,
+                                  i * DescOffsetWordCount,
+                                  DescOffsetWordCount,
+                                  TrueIOArea_p->TokenOffsetWordCount,
+                                  &fLastSegment,
+                                  &fFirstSegment);
+
+            // Stop reading the descriptors if all the requested
+            // packet chains have been read and a new processed packet descriptor
+            // chain is detected
+            if(fFirstSegment && EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
+                break; // for
+
+            if (fFirstSegment)
+                TrueIOArea_p->PacketFound = true;
+
+            GotDscrCount++;
+
+            if(TrueIOArea_p->PacketFound && fLastSegment)
+            {
+                GotPktCount++;
+                TrueIOArea_p->PacketFound = false;
+            }
+
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+    defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+            // Clear this descriptor
+            EIP202_ClearDescriptor(CurrentResultDesc_p,
+                                   TrueIOArea_p->RingHandle,
+                                   i * DescOffsetWordCount,
+                                   TrueIOArea_p->TokenOffsetWordCount,
+                                   DescOffsetWordCount);
+
+            // Ensure next PostDMA does not undo the clear operation above
+            DMAResource_PreDMA(
+                TrueIOArea_p->RingHandle,
+                i * DescOffsetWordCount * (unsigned int)sizeof(uint32_t),
+                DescOffsetWordCount * (unsigned int)sizeof(uint32_t));
+#endif
+        }
+        else
+        {
+            // The fGotDescriptor is set in EIP202_ReadDescriptor() and
+            // depends on the Application ID field in the result descriptor
+            // when EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS is defined.
+            // In case of a packet descriptor chain the Engine writes the
+            // Application ID field for the last segment descriptor only
+            // but we need to acknowledge all the descriptors of the chain
+            break; // for
+        }
+    } // for
+
+    // Check if there are processed result descriptors and packets
+    // that must be acknowledged
+    if (GotDscrCount > 0)
+    {
+        unsigned int NewGotPktCount;
+
+#if EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG != 1
+        GotPktCount = 0;
+#endif
+
+        // EIP-202 HW limits the number of packets to acknowledge at once to
+        // EIP202_RING_MAX_RD_PACKET_COUNT packets
+        NewGotPktCount = MIN(GotPktCount, EIP202_RING_MAX_RD_PACKET_COUNT);
+
+        // CDS point: hand over read Result Descriptors to the Device
+        EIP202_RDR_PROC_COUNT_WR(
+                Device,
+                (uint16_t)(GotDscrCount * DescOffsetWordCount),
+                (uint8_t)NewGotPktCount,
+                false);
+    }
+
+    // Update acknowledged packets counter
+    TrueIOArea_p->AcknowledgedPktCount += GotPktCount;
+
+    // Update acknowledged descriptors counter
+    TrueIOArea_p->AcknowledgedRDCount += GotDscrCount;
+
+    return (int)GotDscrCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_StatusCB
+ */
+int
+EIP202_RDR_StatusCB(
+        void * const CallbackParam1_p,
+        const int CallbackParam2,
+        int * const DeviceReadPos_p)
+{
+    IDENTIFIER_NOT_USED(CallbackParam1_p);
+    IDENTIFIER_NOT_USED(CallbackParam2);
+
+    *DeviceReadPos_p = -1;  // not used
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+  Descriptor I/O Driver Library API implementation
+  ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    int FillLevel;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    FillLevel = RingHelper_FillLevel_Get(
+            (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+
+    if(FillLevel < 0)
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+    else
+    {
+        *FillLevelDscrCount_p = (unsigned int)FillLevel;
+        return EIP202_RING_NO_ERROR;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Prepared_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Prepared_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    Device_Handle_t Device;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    Device = TrueIOArea_p->Device;
+
+    return EIP202Lib_RDR_Prepared_FillLevel_Get(Device,
+                                               TrueIOArea_p,
+                                               FillLevelDscrCount_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Write_Prepared_ControlWord
+ *
+ * This helper function returns the control word that can be written to
+ * the logical prepared descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_RDR_Write_Prepared_ControlWord(
+        const EIP202_RDR_Prepared_Control_t * const  PreparedCtrl_p)
+{
+    return EIP202_RD_Make_ControlWord(PreparedCtrl_p->ExpectedResultWordCount,
+                                     PreparedCtrl_p->PrepSegmentByteCount,
+                                     PreparedCtrl_p->fFirstSegment,
+                                     PreparedCtrl_p->fLastSegment);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Prepare
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Prepare(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const EIP202_ARM_PreparedDescriptor_t * PreparedDscr_p,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrPreparedCount_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    int res, FillLevel;
+    unsigned int RDWordCount, RDFreeCount, DscrNewRequestedCount;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(PreparedDscr_p);
+    EIP202_RING_CHECK_POINTER(DscrPreparedCount_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    // Check how many more descriptors can be added (prepared) to RDR
+    FillLevel = RingHelper_FillLevel_Get(
+            (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+    if(FillLevel < 0)
+        return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
+
+    // Check if RDR is full
+    RDWordCount = ((unsigned int)FillLevel *
+            (unsigned int)TrueIOArea_p->DescOffsWordCount);
+    if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+    {
+        // RD Ring is full
+        *FillLevelDscrCount_p = (unsigned int)FillLevel;
+        *DscrPreparedCount_p = 0;
+
+        // Remain in the current state
+        return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                   (EIP202_RDR_State_t)TrueIOArea_p->State);
+    }
+
+    // Calculate the maximum number of descriptors that can be added to RDR
+    RDFreeCount =
+            ((unsigned int)TrueIOArea_p->RingSizeWordCount - RDWordCount) /
+                    (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    DscrNewRequestedCount = MIN(RDFreeCount, DscrRequestedCount);
+
+    res = RingHelper_Put((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+                         PreparedDscr_p,
+                         (int)DscrNewRequestedCount);
+    if(res >= 0)
+        *DscrPreparedCount_p = (unsigned int)res;
+    else
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Get the current RDR fill level
+    FillLevel = RingHelper_FillLevel_Get(
+            (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+    if(FillLevel < 0)
+        return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
+    else
+    {
+        *FillLevelDscrCount_p = (unsigned int)FillLevel;
+        return EIP202_RING_NO_ERROR;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        unsigned int * FillLevelDscrCount_p,
+        unsigned int * FillLevelPktCount_p)
+{
+// If configured then the driver cannot rely on the register counter
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+    defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+    IDENTIFIER_NOT_USED(FillLevelDscrCount_p);
+    IDENTIFIER_NOT_USED(FillLevelPktCount_p);
+    IDENTIFIER_NOT_USED(IOArea_p);
+
+    return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+#else
+    Device_Handle_t Device;
+    unsigned int RDWordCount, PktCount;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+    EIP202_RING_CHECK_POINTER(FillLevelPktCount_p);
+
+    Device = TrueIOArea_p->Device;
+
+    {
+        uint8_t Value8;
+        uint32_t Value32;
+
+        EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
+
+        RDWordCount = (unsigned int)Value32;
+        PktCount = (unsigned int)Value8;
+    }
+
+    return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
+                                                     PktCount,
+                                                     TrueIOArea_p,
+                                                     FillLevelDscrCount_p,
+                                                     FillLevelPktCount_p);
+#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_ControlWord
+ */
+void
+EIP202_RDR_Read_Processed_ControlWord(
+        EIP202_ARM_ResultDescriptor_t * const  ResDscr_p,
+        EIP202_RDR_Result_Control_t * const RDControl_p,
+        EIP202_RDR_Result_Token_t * const ResToken_p)
+{
+    IDENTIFIER_NOT_USED(ResToken_p);
+
+    EIP202_RD_Read_ControlWord(ResDscr_p->ProcControlWord,
+                               NULL,
+                               RDControl_p,
+                               NULL);
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_BypassData
+ */
+void
+EIP202_RDR_Read_Processed_BypassData(
+        const EIP202_RDR_Result_Token_t * const  ResToken_p,
+        EIP202_RDR_BypassData_t * const BD_p)
+{
+    EIP202_RD_Read_BypassData(ResToken_p->BypassData_p,
+                              ResToken_p->BypassWordCount,
+                              BD_p);
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_ARM_ResultDescriptor_t * ResultDscr_p,
+        const unsigned int PktRequestedCount,
+        const unsigned int DscrRequestedCount,
+        unsigned int * const DscrDoneCount_p,
+        unsigned int * FillLevelDscrCount_p)
+{
+    Device_Handle_t Device;
+    int res;
+    unsigned int RDWordCount, ProcDsrcCount, ProcPktCount;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(ResultDscr_p);
+    EIP202_RING_CHECK_POINTER(DscrDoneCount_p);
+    EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+    if(DscrRequestedCount == 0)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    // Check how many descriptors can be obtained
+    {
+        uint8_t Value8;
+        uint32_t Value32;
+
+#ifdef EIP202_RDR_OWNERSHIP_WORD_ENABLE
+        Value32 = MIN(PktRequestedCount, DscrRequestedCount);
+        Value8  = MIN(EIP202_RING_MAX_RD_PACKET_COUNT, Value32);
+        Value32 = Value8 * TrueIOArea_p->DescOffsWordCount;
+        IDENTIFIER_NOT_USED(Device);
+#else
+        EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
+#endif
+        RDWordCount = (unsigned int)Value32;
+        ProcPktCount = (unsigned int)Value8;
+    }
+
+    // Check if RDR is empty or
+    // if RDR has no fully processed packet descriptor chain
+    if(RDWordCount == 0 ||
+       (PktRequestedCount != 0 && ProcPktCount == 0))
+    {
+        // Nothing to do
+        *FillLevelDscrCount_p = 0;
+        *DscrDoneCount_p = 0;
+
+        return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                   EIP202_RDR_STATE_INITIALIZED);
+    }
+
+    ProcDsrcCount = RDWordCount /
+                    (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+    TrueIOArea_p->AcknowledgedRDCount = 0;
+    TrueIOArea_p->AcknowledgedPktCount = 0;
+    TrueIOArea_p->RDToGetCount = MIN(ProcDsrcCount, DscrRequestedCount);
+    TrueIOArea_p->PktToGetCount = MIN(ProcPktCount, PktRequestedCount);
+
+    // Get processed (result) descriptors
+    res = RingHelper_Get((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+// If configured then the driver cannot rely on the register counter
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+    defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+                         -1, // Certainly available RD count unknown
+#else
+                         (int)TrueIOArea_p->RDToGetCount,
+#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+                         ResultDscr_p,
+                         (int)DscrRequestedCount);
+    if(res >= 0)
+        *DscrDoneCount_p = (unsigned int)res;
+    else
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Increase the fill level by the number of successfully got descriptors
+    RDWordCount -= ((unsigned int)res *
+                         (unsigned int)TrueIOArea_p->DescOffsWordCount);
+
+    // Increase the fill level by the number of acknowledged packets
+    ProcPktCount -= TrueIOArea_p->AcknowledgedPktCount;
+
+    return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
+                                                     ProcPktCount,
+                                                     TrueIOArea_p,
+                                                     FillLevelDscrCount_p,
+                                                     &ProcPktCount);
+}
+
+
+/* end of file eip202_rdr_dscr.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c
new file mode 100644
index 0000000..6f6efc8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c
@@ -0,0 +1,230 @@
+/* eip202_rdr_event.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Event Management API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h"         // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h"             // RDR State machine
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Status_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Status_Get(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RDR_Status_t * const Status_p)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+    EIP202_RING_CHECK_POINTER(Status_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202_RDR_PREP_COUNT_RD(Device, &Status_p->RDPrepWordCount);
+    EIP202_RDR_PROC_COUNT_RD(Device,
+                             &Status_p->RDProcWordCount,
+                             &Status_p->RDProcPktWordCount);
+
+    EIP202_RDR_STAT_RD(Device,
+                       &Status_p->fDMAError,
+                       &Status_p->fTresholdInt,
+                       &Status_p->fError,
+                       &Status_p->fOUFlowError,
+                       &Status_p->fTimeoutInt,
+                       &Status_p->fRDBufOverflowInt,
+                       &Status_p->fRDOverflowInt,
+                       &Status_p->RDFIFOWordCount);
+
+    // Transit to a new state
+    if(Status_p->fDMAError)
+        rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                 EIP202_RDR_STATE_FATAL_ERROR);
+    else
+        // Remain in the current state
+        rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                                 (EIP202_RDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_Enable
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_Enable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const unsigned int ThresholdDscrCount,
+        const unsigned int Timeout,
+        const bool fIntPerPacket)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    if(EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG == 0 && fIntPerPacket)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    if (fIntPerPacket)
+    {
+        EIP202_RDR_THRESH_WR(Device,
+                             (uint32_t)ThresholdDscrCount,
+                             // Set packet processing mode,
+                             // e.g. interrupts per packet i.s.o. descriptor
+                             true,
+                             (uint8_t)Timeout);
+    }
+    else
+    {
+        EIP202_RDR_THRESH_WR(Device,
+                             (uint32_t)ThresholdDscrCount *
+                             TrueIOArea_p->DescOffsWordCount,
+                             // Set packet processing mode,
+                             // e.g. interrupts per packet i.s.o. descriptor
+                             false,
+                             (uint8_t)Timeout);
+    }
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+    // Prevent clustered write operations, break them with a read operation
+    // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+    //       has no side effects!
+    EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+
+    // Remain in the current state
+    rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                             (EIP202_RDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const bool fOvflIntOnly)
+{
+    Device_Handle_t Device;
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    if(fOvflIntOnly)
+    {
+        // Clear Descriptor and Buffer overflow interrupts
+        EIP202_RDR_STAT_CLEAR_DSCR_BUF_OFLO_IRQ_WR(Device);
+    }
+    else
+    {
+        // Disable Processed Descriptor threshold interrupt,
+        // Disable Timeout interrupt and stop timeout counter for
+        // reducing power consumption
+        EIP202_RDR_THRESH_WR(
+                           Device,
+                           TrueIOArea_p->RingSizeWordCount,
+                           0,  // Set descriptor processing mode
+                           0); // Disable timeout
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+        // Prevent clustered write operations, break them with a read operation
+        // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+        //       has no side effects!
+        EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+
+        // Clear all RDR interrupts
+        EIP202_RDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+        // Prevent clustered write operations, break them with a read operation
+        // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+        //       has no side effects!
+        EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+    }
+
+    // Remain in the current state
+    rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                             (EIP202_RDR_State_t)TrueIOArea_p->State);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_rdr_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c
new file mode 100644
index 0000000..a3fa0e5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c
@@ -0,0 +1,174 @@
+/* eip202_rdr_fsm.c
+ *
+ * EIP-202 Ring Control Driver Library API
+ * State Machine Internal Interface implementation for RDR
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"              // IDENTIFIER_NOT_USED
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h"        // EIP202_Ring_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_State_Set
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_State_Set(
+        volatile EIP202_RDR_State_t * const CurrentState,
+        const EIP202_RDR_State_t NewState)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+    switch(*CurrentState)
+    {
+        case EIP202_RDR_STATE_UNKNOWN:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+         case EIP202_RDR_STATE_UNINITIALIZED:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_INITIALIZED:
+                   *CurrentState = NewState;
+                   break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_RDR_STATE_INITIALIZED:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_RDR_STATE_FREE:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_RDR_STATE_FULL:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FREE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                case EIP202_RDR_STATE_FULL:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP202_RDR_STATE_FATAL_ERROR:
+            switch(NewState)
+            {
+                case EIP202_RDR_STATE_UNINITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP202_RING_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        default:
+            return EIP202_RING_ILLEGAL_IN_STATE;
+    }
+#else
+    IDENTIFIER_NOT_USED(CurrentState);
+    IDENTIFIER_NOT_USED(NewState);
+#endif // EIP202_RING_DEBUG_FSM
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_rdr_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c
new file mode 100644
index 0000000..6fd658c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c
@@ -0,0 +1,372 @@
+/* eip202_rdr_init.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * RDR Init/Reset API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h"          // EIP202_Ring_* types
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h"          // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h"             // RDR State machine
+#include "eip202_rdr_dscr.h"            // RingHelper callbacks
+#include "eip202_rd_format.h"           // EIP-202 Result Descriptor
+
+// RingHelper API
+#include "ringhelper.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"              // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"         // types of the DMA resource API
+#include "dmares_rw.h"            // read/write of the DMA resource API.
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"
+
+// Standard IOToken API
+#include "iotoken.h"                   // IOToken_InWordCount_Get()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_Detect
+ *
+ * Checks the presence of EIP-202 HIA hardware. Returns true when found.
+ */
+static bool
+EIP202Lib_RDR_Detect(
+        const Device_Handle_t Device)
+{
+    uint32_t Value;
+
+    // read-write test one of the registers
+
+    // Set MASK_31_BITS bits of the EIP202_RDR_RING_BASE_ADDR_LO register
+    EIP202_RDR_Write32(Device,
+                       EIP202_RDR_RING_BASE_ADDR_LO,
+                       MASK_31_BITS );
+
+    Value = EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+    if ((Value & MASK_31_BITS) != MASK_31_BITS)
+        return false;
+
+    // Clear MASK_31_BITS bits of the EIP202_RDR_RING_BASE_ADDR_LO register
+    EIP202_RDR_Write32(Device, EIP202_RDR_RING_BASE_ADDR_LO, 0);
+    Value = EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+    if ((Value & MASK_31_BITS) != 0)
+       return false;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_ClearAllDescriptors
+ *
+ * Clear all descriptors
+ */
+static inline void
+EIP202Lib_RDR_ClearAllDescriptors(
+        DMAResource_Handle_t Handle,
+        const uint32_t DescriptorSpacingWordCount,
+        const uint32_t DescriptorSizeWordCount,
+        const uint32_t NumberOfDescriptors)
+{
+    unsigned int i, j;
+
+    for(i = 0; i < NumberOfDescriptors; i++)
+        for(j = 0; j < DescriptorSizeWordCount; j++)
+            DMAResource_Write32(Handle, i * DescriptorSpacingWordCount + j, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Init
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Init(
+        EIP202_Ring_IOArea_t * IOArea_p,
+        const Device_Handle_t Device,
+        const EIP202_RDR_Settings_t * const RDRSettings_p)
+{
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    // Initialize the IO Area
+    TrueIOArea_p->Device = Device;
+    TrueIOArea_p->State = (unsigned int)EIP202_RDR_STATE_UNINITIALIZED;
+
+    // Check if the CPU integer size is enough to store 32-bit value
+    if(sizeof(unsigned int) < sizeof(uint32_t))
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    // Detect presence of EIP-202 CDR hardware
+    if(!EIP202Lib_RDR_Detect(Device))
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    // Extension of 32-bit pointers to 64-bit addresses not supported.
+    if(RDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_EXT_ADDR)
+        return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+    if(RDRSettings_p->Params.DscrOffsWordCount == 0 ||
+       RDRSettings_p->Params.DscrOffsWordCount <
+       RDRSettings_p->Params.DscrSizeWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Ring size cannot be smaller than one descriptor size or
+    // larger than 4194303 (16MB / 4 - 1), in 32-bit words
+    if(RDRSettings_p->Params.RingSizeWordCount <
+       RDRSettings_p->Params.DscrOffsWordCount ||
+       RDRSettings_p->Params.RingSizeWordCount > 4194303)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if(RDRSettings_p->Params.DscrSizeWordCount >
+             RDRSettings_p->Params.TokenOffsetWordCount + IOToken_OutWordCount_Get())
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if(RDRSettings_p->Params.DscrFetchSizeWordCount %
+                            RDRSettings_p->Params.DscrOffsWordCount)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    if( RDRSettings_p->Params.IntThresholdDscrCount *
+            RDRSettings_p->Params.DscrOffsWordCount >
+                      RDRSettings_p->Params.RingSizeWordCount )
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Configure the Ring Helper
+    TrueIOArea_p->RingHelperCallbacks.WriteFunc_p = &EIP202_RDR_WriteCB;
+    TrueIOArea_p->RingHelperCallbacks.ReadFunc_p = &EIP202_RDR_ReadCB;
+    TrueIOArea_p->RingHelperCallbacks.StatusFunc_p = &EIP202_RDR_StatusCB;
+    TrueIOArea_p->RingHelperCallbacks.CallbackParam1_p = IOArea_p;
+    TrueIOArea_p->RingHelperCallbacks.CallbackParam2 = 0;
+    TrueIOArea_p->RingHandle = RDRSettings_p->Params.RingDMA_Handle;
+    TrueIOArea_p->DescOffsWordCount = RDRSettings_p->Params.DscrOffsWordCount;
+    TrueIOArea_p->RingSizeWordCount = RDRSettings_p->Params.RingSizeWordCount;
+    TrueIOArea_p->TokenOffsetWordCount = RDRSettings_p->Params.TokenOffsetWordCount;
+    TrueIOArea_p->PacketFound = false;
+
+    // Initialize one RingHelper instance for one RDR instance
+    if( RingHelper_Init(
+         (volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+         (volatile RingHelper_CallbackInterface_t*)&TrueIOArea_p->RingHelperCallbacks,
+         false, // One RDR as combined rings
+         (unsigned int)(RDRSettings_p->Params.RingSizeWordCount /
+             RDRSettings_p->Params.DscrOffsWordCount),
+         (unsigned int)(RDRSettings_p->Params.RingSizeWordCount /
+             RDRSettings_p->Params.DscrOffsWordCount)) < 0)
+        return EIP202_RING_ARGUMENT_ERROR;
+
+    // Transit to a new state
+    rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                             EIP202_RDR_STATE_INITIALIZED);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    // Prepare the RDR DMA buffer
+    // Initialize all descriptors with zero for RDR
+    EIP202Lib_RDR_ClearAllDescriptors(
+            TrueIOArea_p->RingHandle,
+            RDRSettings_p->Params.DscrOffsWordCount,
+            RDRSettings_p->Params.DscrSizeWordCount,
+            RDRSettings_p->Params.RingSizeWordCount /
+                 RDRSettings_p->Params.DscrOffsWordCount);
+
+    // Call PreDMA to make sure engine sees it
+    DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+                       0,
+                       (unsigned int)(TrueIOArea_p->RingSizeWordCount*4));
+
+    EIP202_RDR_RING_BASE_ADDR_LO_WR(
+                       Device,
+                       RDRSettings_p->Params.RingDMA_Address.Addr);
+
+    EIP202_RDR_RING_BASE_ADDR_HI_WR(
+                       Device,
+                       RDRSettings_p->Params.RingDMA_Address.UpperAddr);
+
+    EIP202_RDR_RING_SIZE_WR(
+                       Device,
+                       RDRSettings_p->Params.RingSizeWordCount);
+
+    EIP202_RDR_DESC_SIZE_WR(
+                       Device,
+                       RDRSettings_p->Params.DscrSizeWordCount,
+                       RDRSettings_p->Params.DscrOffsWordCount,
+                       RDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_DSCR_PTR);
+
+    EIP202_RDR_CFG_WR(Device,
+                      RDRSettings_p->Params.DscrFetchSizeWordCount,
+                      RDRSettings_p->Params.DscrThresholdWordCount,
+#ifdef EIP202_RDR_OWNERSHIP_WORD_ENABLE
+                      true);  // Ownership write mode
+#else
+                      RDRSettings_p->fContinuousScatter); // Normal mode, no ownership words are used.
+/* Always enable ownership words for continuous scatter */
+#endif
+
+    // Disable Processed Descriptor threshold interrupt,
+    // Disable Timeout interrupt and stop timeout counter for
+    // reducing power consumption
+    EIP202_RDR_THRESH_WR(
+                       Device,
+                       TrueIOArea_p->RingSizeWordCount,
+                       0,  // Set descriptor processing mode
+                       0); // Disable timeout
+
+    EIP202_RDR_DMA_CFG_WR(
+                       Device,
+                       (uint8_t)RDRSettings_p->Params.ByteSwap_Descriptor_Mask,
+                       (uint8_t)RDRSettings_p->Params.ByteSwap_Packet_Mask,
+
+                       // Bufferability control for DMA writes of
+                       EIP202_RING_RD_RES_BUF,  // result token
+                       EIP202_RING_RD_CTRL_BUF, // descriptor control words
+                       EIP202_RING_RD_OWN_BUF,  // ownership words
+
+                       EIP202_RING_RD_WR_CACHE_CTRL, // Write cache type control
+                       EIP202_RING_RD_RD_CACHE_CTRL, // Read cache type control
+                       EIP202_RING_RD_PROT_VALUE,
+                       EIP202_RING_DATA_PROT_VALUE,
+                       RDRSettings_p->fContinuousScatter|EIP202_RDR_PAD_TO_OFFSET); // Result descriptor padding
+/* Note: for continuous scatter: always set RDR_PAD_TO_OFFSET. */
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Reset
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Reset(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    EIP202_Ring_Error_t rv;
+    volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+    EIP202_RING_CHECK_POINTER(IOArea_p);
+
+    // Initialize the IO Area
+    memset((void*)IOArea_p, 0, sizeof(*TrueIOArea_p));
+    TrueIOArea_p->Device = Device;
+    TrueIOArea_p->State = (unsigned int)EIP202_RDR_STATE_UNKNOWN;
+
+    // Transit to a new state
+    rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+                             EIP202_RDR_STATE_UNINITIALIZED);
+    if(rv != EIP202_RING_NO_ERROR)
+        return EIP202_RING_ILLEGAL_IN_STATE;
+
+    // Clear RDR count
+    EIP202_RDR_PREP_COUNT_WR(Device, 0, true);
+    EIP202_RDR_PROC_COUNT_WR(Device, 0, 0, true);
+
+    // Re-init RDR
+    EIP202_RDR_PREP_PNTR_DEFAULT_WR(Device);
+    EIP202_RDR_PROC_PNTR_DEFAULT_WR(Device);
+
+    // Restore default register values
+    EIP202_RDR_RING_BASE_ADDR_LO_DEFAULT_WR(Device);
+    EIP202_RDR_RING_BASE_ADDR_HI_DEFAULT_WR(Device);
+    EIP202_RDR_RING_SIZE_DEFAULT_WR(Device);
+    EIP202_RDR_DESC_SIZE_DEFAULT_WR(Device);
+    EIP202_RDR_CFG_DEFAULT_WR(Device);
+    EIP202_RDR_DMA_CFG_DEFAULT_WR(Device);
+    EIP202_RDR_THRESH_DEFAULT_WR(Device);
+
+    // Clear and disable all RDR interrupts
+    EIP202_RDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+    return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Dump
+ *
+ */
+void
+EIP202_RDR_Dump(
+        EIP202_Ring_IOArea_t * const IOArea_p,
+        EIP202_RingAdmin_t * const RingAdmin_p)
+{
+    EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+                            (EIP202_RDR_True_IOArea_t * const)IOArea_p;
+
+    if(!TrueIOArea_p)
+        return;
+
+    if(!RingAdmin_p)
+        return;
+
+    RingAdmin_p->IN_Size           = TrueIOArea_p->RingHelper.IN_Size;
+    RingAdmin_p->IN_Tail           = TrueIOArea_p->RingHelper.IN_Tail;
+    RingAdmin_p->OUT_Size          = TrueIOArea_p->RingHelper.OUT_Size;
+    RingAdmin_p->OUT_Head          = TrueIOArea_p->RingHelper.OUT_Head;
+
+    RingAdmin_p->fSeparate         = TrueIOArea_p->RingHelper.fSeparate;
+
+    RingAdmin_p->DescOffsWordCount = TrueIOArea_p->DescOffsWordCount;
+    RingAdmin_p->RingSizeWordCount = TrueIOArea_p->RingSizeWordCount;
+}
+
+
+/* end of file eip202_rdr_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c
new file mode 100644
index 0000000..6cbdba3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c
@@ -0,0 +1,1837 @@
+/* eip207_flow_dtl.c
+ *
+ * Partial EIP-207 Flow Control Generic API implementation and
+ * full EIP-207 Flow Control DTL API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_dtl.h"
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                       // ZEROINIT, memset, memcpy
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"
+#include "dmares_rw.h"
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_level0.h"         // EIP-207 Level 0 macros
+#include "eip207_flow_hte_dscr_dtl.h"   // HTE descriptor DTL
+#include "eip207_flow_internal.h"
+
+#ifndef EIP207_FLUE_RC_HP
+// EIP-207 (Global Control) Record Cache (RC) interface
+#include "eip207_rc.h"
+
+// EIP-207s (Global Control) Flow Look-Up Engine Cache (FLUEC) interface
+#include "eip207_fluec.h"
+#endif // !EIP207_FLUE_RC_HP
+
+// EIP-207 Firmware API
+#include "firmware_eip207_api_flow_cs.h" // Classification API: Flow Control
+#include "firmware_eip207_api_cs.h"      // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLOW_MAX_RECORDS_PER_BUCKET              3
+
+
+// Flow record input data required for the flow record creation
+typedef struct
+{
+    // Bitwise of zero or more EIP207_FLOW_FLAG_* flags, see above
+    uint32_t Flags;
+
+    // Physical (DMA/bus) address of the transform record
+    EIP207_Flow_Address_t Xform_DMA_Addr;
+
+    // Software flow record reference
+    uint32_t SW_FR_Reference;
+
+    // Transform record type, true - large, false - small
+    bool fLarge;
+} EIP207_Flow_FR_Data_t;
+
+// Transform record input data required for the transform record creation
+typedef struct
+{
+    // Transform record type, true - large, false - small
+    bool fLarge;
+
+} EIP207_Flow_TR_Data_t;
+
+// Transform record input data required for the Transform record creation
+typedef struct
+{
+    // Record hash ID
+    const EIP207_Flow_ID_t * HashID_p;
+
+    // Flow record input data, fill with NULL if not used
+    const EIP207_Flow_FR_Data_t * FR_Data_p;
+
+    // Transform record input data, fill with NULL if not used
+    const EIP207_Flow_TR_Data_t * TR_Data_p;
+
+    // Note: FR_Data_p and TR_Data_p cannot be both NULL!
+
+} EIP207_Flow_Record_InputData_t;
+
+// Full record descriptor
+typedef struct
+{
+    EIP207_Flow_Dscr_t                  RecDscr;
+
+    EIP207_Flow_HTE_Dscr_RecData_t      RecData;
+
+    void *                              Reserved_p;
+} EIP207_Flow_Rec_Dscr_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Entry_Lookup
+ */
+static void
+EIP207Lib_Flow_Entry_Lookup(
+        const uint32_t HashID_Word0,
+        const uint32_t TableSize,
+        unsigned int * const HT_Entry_ByteOffset,
+        unsigned int * const DT_Entry_Index)
+{
+    uint32_t HashID_W0, Mask;
+
+    // From the EIP-197 Programmer Manual:
+    // The hash engine completes the hash ID calculation and
+    // adds bits [(table_size+10):6] (with table_size coming from
+    // the FLUE_SIZE(_VM)_f register) of the hash ID, multiplied by 64,
+    // to the table base address given in the FLUE_HASHBASE(_VM)_f_* registers.
+
+    // Calculate the entry byte offset in the HT for this record
+    HashID_W0 = (HashID_Word0 & (~MASK_6_BITS));
+
+    Mask = (1 << (TableSize + 10 + 1)) - 1;
+
+    // Calculate the HT entry byte offset
+    *HT_Entry_ByteOffset = (unsigned int)(HashID_W0 & Mask);
+
+    // Translate the HT entry byte offset to the index in the HT
+    // HT entry size is one hash bucket (16 words = 64 bytes)
+    *DT_Entry_Index = (*HT_Entry_ByteOffset) >> 6; // divide by 64
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_TableSize_To_EntryCount
+ *
+ * Convert EIP207_Flow_HashTable_Entry_Count_t to a number
+ */
+static inline unsigned int
+EIP207Lib_Flow_TableSize_To_EntryCount(
+        const unsigned int TableSize)
+{
+    return (1 << (TableSize + 5));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HTE_Dscr_ByteCount_Get
+ */
+static inline unsigned int
+EIP207Lib_Flow_HTE_Dscr_ByteCount_Get(void)
+{
+    return sizeof(EIP207_Flow_HTE_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Record_Add
+ *
+ * Updates Hash ID and record offset in the hash bucket,
+ * first Hash ID then record byte offset
+ */
+static inline void
+EIP207Lib_Flow_HB_Record_Add(
+        const DMAResource_Handle_t HT_DMA_Handle,
+        const unsigned int HB_ByteOffset,
+        const unsigned int slot,
+        const uint32_t Rec_ByteOffset,
+        const uint32_t RecType,
+        const EIP207_Flow_ID_t * const HashID_p)
+{
+    unsigned int i;
+    unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+    // Write record Hash ID words
+    for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+        DMAResource_Write32(HT_DMA_Handle,
+                            HB_WordOffset +
+                             EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+                             EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1),
+                            HashID_p->Word32[i]);
+
+    // Write record offset
+    DMAResource_Write32(HT_DMA_Handle,
+                        HB_WordOffset +
+                        EIP207_FLOW_HB_REC_1_WORD_OFFSET + (slot - 1),
+                        Rec_ByteOffset | RecType);
+
+    // Perform pre-DMA for this hash bucket
+    DMAResource_PreDMA(HT_DMA_Handle,
+                       HB_ByteOffset,
+                       EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+                         sizeof(uint32_t));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Record_Remove
+ *
+ * Updates Hash ID and record offset in the hash bucket,
+ * first record byte offset then Hash ID
+ */
+static inline void
+EIP207Lib_Flow_HB_Record_Remove(
+        const DMAResource_Handle_t HT_DMA_Handle,
+        const unsigned int HB_ByteOffset,
+        const unsigned int slot,
+        EIP207_Flow_ID_t * HashID_p)
+{
+    unsigned int i;
+    unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+    EIP207_Flow_ID_t HashID;
+
+    // Write record offset
+    DMAResource_Write32(HT_DMA_Handle,
+                        HB_WordOffset +
+                        EIP207_FLOW_HB_REC_1_WORD_OFFSET + (slot - 1),
+                        EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+    // Read old record Hash ID words
+    for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+        HashID.Word32[i] = DMAResource_Read32(
+                             HT_DMA_Handle,
+                             HB_WordOffset +
+                             EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+                             EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1));
+
+    // Write new record Hash ID words
+    for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+    {
+        DMAResource_Write32(HT_DMA_Handle,
+                            HB_WordOffset +
+                             EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+                             EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1),
+                            HashID_p->Word32[i]);
+
+        // Store old record Hash ID words
+        HashID_p->Word32[i] = HashID.Word32[i];
+    }
+
+    // Perform pre-DMA for this hash bucket
+    DMAResource_PreDMA(HT_DMA_Handle,
+                       HB_ByteOffset,
+                       EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+                         sizeof(uint32_t));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_BuckOffs_Update
+ *
+ * Update bucket offset in the hash bucket (identified by HB_ByteOffset)
+ * by writing the Update_Value in there
+ */
+static inline void
+EIP207Lib_Flow_HB_BuckOffs_Update(
+        const DMAResource_Handle_t HT_DMA_Handle,
+        const unsigned int HB_ByteOffset,
+        const uint32_t Update_Value)
+{
+    unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+    // Write record offset
+    DMAResource_Write32(HT_DMA_Handle,
+                        HB_WordOffset +
+                        EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET,
+                        Update_Value);
+
+    // Perform pre-DMA for this hash bucket
+    DMAResource_PreDMA(HT_DMA_Handle,
+                       HB_ByteOffset,
+                       EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+                         sizeof(uint32_t));
+}
+
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_HashID_Match
+ *
+ * Checks if the hash bucket already contains this Hash ID
+ */
+static bool
+EIP207Lib_Flow_HB_HashID_Match(
+        const DMAResource_Handle_t HT_DMA_Handle,
+        const unsigned int HB_ByteOffset,
+        const uint32_t RecType,
+        const EIP207_Flow_ID_t * const HashID_p)
+{
+    uint32_t Word32;
+    bool fMatch;
+    unsigned int i, j;
+    unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+    // Read Hash ID's from the bucket
+    // (this DMA resource is read-only for the FLUE device)
+    for (i = 0; i < EIP207_FLOW_HTE_BKT_NOF_REC_MAX; i++)
+    {
+        for (j = 0; j < EIP207_FLOW_HASH_ID_WORD_COUNT; j++)
+        {
+            fMatch = true;
+
+            Word32 = DMAResource_Read32(
+                                 HT_DMA_Handle,
+                                 HB_WordOffset +
+                                  EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET +
+                                    i * EIP207_FLOW_HASH_ID_WORD_COUNT + j);
+
+            if (Word32 != HashID_p->Word32[j])
+            {
+                fMatch = false;
+                break; // No match, skip this hash ID
+            }
+        } // for
+
+        if (fMatch)
+            break; // Matching Hash ID found, stop searching
+    } // for
+
+    if (fMatch)
+    {
+        uint32_t Match_RecType;
+
+        // Check the record type in the record offset for Hash ID with index i
+        // to confirm the match
+        Word32 = DMAResource_Read32(
+                             HT_DMA_Handle,
+                             HB_WordOffset +
+                              EIP207_FLOW_HB_REC_1_WORD_OFFSET + i);
+
+        // Note: small transform record and large transform record
+        //       fall under the same record type for this check!
+        Match_RecType = Word32 & RecType;
+
+        if ((Match_RecType == EIP207_FLOW_RECORD_FR_ADDRESS  &&
+             (RecType == EIP207_FLOW_RECORD_TR_ADDRESS         ||
+              RecType == EIP207_FLOW_RECORD_TR_LARGE_ADDRESS))    ||
+
+            (RecType == EIP207_FLOW_RECORD_FR_ADDRESS        &&
+             (Match_RecType == EIP207_FLOW_RECORD_TR_ADDRESS   ||
+              Match_RecType == EIP207_FLOW_RECORD_TR_LARGE_ADDRESS)))
+        {
+            // Match not confirmed, a different record type is used
+            fMatch = false;
+        }
+    }
+
+    return fMatch;
+}
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Slot_Get
+ *
+ * Determine the free offset slot number (1,2 or 3) and claim it
+ */
+static inline EIP207_Flow_Error_t
+EIP207Lib_Flow_HB_Slot_Get(
+        uint32_t * const RecOffsMask_p,
+        unsigned int * FreeSlot_p)
+{
+    if ((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_1) == 0)
+    {
+        *FreeSlot_p = 1;
+        *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_1;
+    }
+    else if((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_2) == 0)
+    {
+        *FreeSlot_p = 2;
+        *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_2;
+    }
+    else if((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_3) == 0)
+    {
+        *FreeSlot_p = 3;
+        *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_3;
+    }
+    else
+        // Consistency checks for the found HTE descriptor
+        return EIP207_FLOW_INTERNAL_ERROR;
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Slot_Put
+ *
+ * Determine the used offset slot number (1,2 or 3) and release it
+ */
+static inline EIP207_Flow_Error_t
+EIP207Lib_Flow_HB_Slot_Put(
+        uint32_t * const RecOffsMask_p,
+        const unsigned int Slot)
+{
+    switch (Slot)
+    {
+        case 1:
+            *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_1;
+            break;
+
+        case 2:
+            *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_2;
+            break;
+
+        case 3:
+            *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_3;
+            break;
+
+        default:
+            // Consistency checks for the slot to release
+            return EIP207_FLOW_INTERNAL_ERROR;
+    }
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Dscr_InternalData_Set
+ */
+static inline void
+EIP207Lib_Flow_Dscr_InternalData_Set(
+        EIP207_Flow_Dscr_t * const Dscr_p)
+{
+    EIP207_Flow_Rec_Dscr_t * p = (EIP207_Flow_Rec_Dscr_t*)Dscr_p;
+
+    Dscr_p->InternalData_p = &p->RecData;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_FR_Write
+ */
+static void
+EIP207Lib_Flow_FR_Write(
+        const DMAResource_Handle_t DMA_Handle,
+        const EIP207_Flow_FR_Data_t * const FR_Data_p,
+        const uint32_t Xform_ByteOffset,
+        const uint32_t Xform_Addr,
+        const uint32_t Xform_UpperAddr)
+{
+    unsigned int i;
+    uint32_t Record_Type;
+
+    // Write flow record with 0's
+    for (i = 0; i < FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT; i++)
+        DMAResource_Write32(DMA_Handle, i, 0);
+
+#ifdef EIP207_FLOW_NO_TYPE_BITS_IN_FLOW_RECORD
+    Record_Type = 0;
+#else
+    Record_Type = FR_Data_p->fLarge ?
+        EIP207_FLOW_RECORD_TR_LARGE_ADDRESS :
+        EIP207_FLOW_RECORD_TR_ADDRESS;
+#endif
+
+    // Write Transform Record 32-bit offset
+    DMAResource_Write32(DMA_Handle,
+                        FIRMWARE_EIP207_CS_FLOW_FR_XFORM_OFFS_WORD_OFFSET,
+                        Xform_ByteOffset + Record_Type);
+
+    // Write Transform Record low half of 64-bit address
+    DMAResource_Write32(DMA_Handle,
+                        FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_WORD_OFFSET,
+                        Xform_Addr + Record_Type);
+
+    // Write Transform Record high half of 64-bit address
+    DMAResource_Write32(DMA_Handle,
+                        FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_HI_WORD_OFFSET,
+                        Xform_UpperAddr);
+
+    // Not supported yet
+    // Write ARC4 State Record physical address
+    //DMAResource_Write32(FR_Dscr_p->Data.DMA_Handle,
+    //                    FIRMWARE_EIP207_CS_FLOW_FR_ARC4_ADDR_WORD_OFFSET,
+    //                    EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+    // Write Software Flow Record Reference
+    // NOTE: this is a 32-bit value!
+    DMAResource_Write32(DMA_Handle,
+                        FIRMWARE_EIP207_CS_FLOW_FR_SW_ADDR_WORD_OFFSET,
+                        FR_Data_p->SW_FR_Reference);
+
+    // Write the Flags field
+    DMAResource_Write32(DMA_Handle,
+                        FIRMWARE_EIP207_CS_FLOW_FR_FLAGS_WORD_OFFSET,
+                        FR_Data_p->Flags);
+
+    // Perform pre-DMA for the entire flow record
+    DMAResource_PreDMA(DMA_Handle, 0, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_DTL_Record_Add
+ */
+static EIP207_Flow_Error_t
+EIP207Lib_Flow_DTL_Record_Add(
+        volatile EIP207_Flow_HT_Params_t * const HT_Params_p,
+        EIP207_Flow_Dscr_t * const Rec_Dscr_p,
+        const EIP207_Flow_Record_InputData_t * const RecData_p)
+{
+    uint32_t Rec_ByteOffset;
+    unsigned int slot = 0;
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Updated_p = NULL;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+    // Consistency check for the provided record descriptor
+    if (Rec_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+        return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+    // Add the record to the Hash Table
+    {
+        EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p;
+        unsigned int Entry_Index, HTE_ByteOffset, HT_TableSize;
+        uint32_t Record_Type = EIP207_FLOW_RECORD_DUMMY_ADDRESS;
+        DMAResource_Handle_t HT_DMA_Handle = HT_Params_p->HT_DMA_Handle;
+
+        // Transform record
+        if (RecData_p->TR_Data_p != NULL)
+            Record_Type = RecData_p->TR_Data_p->fLarge ?
+                            EIP207_FLOW_RECORD_TR_LARGE_ADDRESS :
+                                       EIP207_FLOW_RECORD_TR_ADDRESS;
+        // Flow record
+        else if (RecData_p->FR_Data_p != NULL)
+            Record_Type = EIP207_FLOW_RECORD_FR_ADDRESS;
+        else
+            return EIP207_FLOW_INTERNAL_ERROR; // Unknown record, error
+
+        HT_TableSize = HT_Params_p->HT_TableSize;
+
+        HTE_ByteOffset  = 0;
+        Entry_Index     = 0;
+
+        EIP207Lib_Flow_Entry_Lookup(
+                RecData_p->HashID_p->Word32[0], // Word 0 is used for lookup
+                HT_TableSize,
+                &HTE_ByteOffset,
+                &Entry_Index);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+        {
+            unsigned int HT_EntryCount =
+                    EIP207Lib_Flow_TableSize_To_EntryCount(HT_TableSize);
+
+            if (Entry_Index >= HT_EntryCount)
+                return EIP207_FLOW_INTERNAL_ERROR;
+        }
+#endif
+
+        // Calculate the record byte offset,
+        // HT_Params_p->BaseAddr.Addr is the base
+        // address of the DMA bank where the record
+        // must have been allocated
+        Rec_ByteOffset = Rec_Dscr_p->DMA_Addr.Addr - HT_Params_p->BaseAddr.Addr;
+
+        // Convert the DT entry index to the HTE descriptor pointer
+        {
+            void * p;
+            unsigned char * DT_p = (unsigned char*)HT_Params_p->DT_p;
+
+            // Read the entry value at the calculated offset from the DT
+            p = DT_p + Entry_Index * EIP207Lib_Flow_HTE_Dscr_ByteCount_Get();
+
+            HTE_Dscr_p = (EIP207_Flow_HTE_Dscr_t*)p;
+        }
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+        // Consistency checks for the found HTE descriptor
+        if (HTE_Dscr_p->Bucket_ByteOffset != (uint32_t)HTE_ByteOffset)
+            return EIP207_FLOW_INTERNAL_ERROR;
+
+        // Check that this HTE is not an overflow one
+        if (HTE_Dscr_p->fOverflowBucket)
+            return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+        do // Walk the bucket chain, look for bucket where record can be added
+        {
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+            if (HTE_Dscr_p->RecordCount > EIP207_FLOW_MAX_RECORDS_PER_BUCKET)
+                return EIP207_FLOW_INTERNAL_ERROR;
+
+            // Check if the hash bucket does not contain this Hash ID already
+            if (HTE_Dscr_Updated_p == NULL && EIP207Lib_Flow_HB_HashID_Match(
+                     HT_DMA_Handle,
+                     HTE_Dscr_p->Bucket_ByteOffset,
+                     Record_Type,
+                     RecData_p->HashID_p))
+                return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+            // Check if the found hash bucket can be used to add
+            // the record or a next bucket in the chain must be used
+            if (HTE_Dscr_p->RecordCount < EIP207_FLOW_MAX_RECORDS_PER_BUCKET)
+            {
+                uint32_t TempMask = HTE_Dscr_p->UsedRecOffsMask;
+                uint32_t TempSlot = slot;
+
+                // Use the found bucket to add the record
+
+                // Determine the offset slot (1,2 or 3) where the record offset
+                // and Hash ID can be stored
+                {
+                    EIP207_Flow_Error_t Flow_Rc =
+                            EIP207Lib_Flow_HB_Slot_Get(
+                                    &TempMask,
+                                    &TempSlot);
+
+                    if(Flow_Rc != EIP207_FLOW_NO_ERROR)
+                        return Flow_Rc;
+                }
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+                // Check if the record offset in the HTE slot is a dummy pointer
+                {
+                    // Read record offset
+                    // (this DMA resource is read-only for the FLUE device)
+                    uint32_t Record_ByteOffset =
+                                DMAResource_Read32(
+                                         HT_DMA_Handle,
+                                         (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+                                           EIP207_FLOW_HB_REC_1_WORD_OFFSET +
+                                            (TempSlot - 1));
+
+                    if ((Record_ByteOffset &
+                         EIP207_FLOW_RECORD_ADDRESS_TYPE_BITS) !=
+                            EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+                        return EIP207_FLOW_INTERNAL_ERROR;
+                }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+                // Add the record only if it has not been done already
+                if (HTE_Dscr_Updated_p == NULL)
+                {
+                    HTE_Dscr_p->UsedRecOffsMask = TempMask;
+                    slot = TempSlot;
+
+                    // If flow record is added then write it
+                    if (RecData_p->FR_Data_p != NULL)
+                        EIP207Lib_Flow_FR_Write(
+                                 Rec_Dscr_p->DMA_Handle,
+                                 RecData_p->FR_Data_p,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.Addr -
+                                 HT_Params_p->BaseAddr.Addr,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.Addr,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.UpperAddr);
+
+                    // Update the found hash bucket with the
+                    // record Hash ID and offset
+
+                    // CDS point: after this operation is done the FLUE
+                    //            hardware can find the transform record!
+                    EIP207Lib_Flow_HB_Record_Add(HT_DMA_Handle,
+                                             HTE_Dscr_p->Bucket_ByteOffset,
+                                             slot,
+                                             Rec_ByteOffset,
+                                             Record_Type,
+                                             RecData_p->HashID_p);
+
+                    // Increase the HTE descriptor record count
+                    // for the added record
+                    HTE_Dscr_p->RecordCount++;
+                }
+
+                // The found HTE is updated, record is added
+                if (HTE_Dscr_Updated_p == NULL)
+                    HTE_Dscr_Updated_p = HTE_Dscr_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+                // Get the next HTE descriptor in the chain
+                HTE_Dscr_p = EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+                continue; // Validate the entire chain
+#else
+                break;
+#endif
+            }
+            else // Found bucket record count is max possible
+            {
+                EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p;
+
+                // Use a next overflow bucket to add the record, find a bucket
+                // in the chain with a free slot for the new record
+
+                // Get the next HTE descriptor in the chain
+                HTE_Dscr_Next_p =
+                           EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+
+                // Check if we have one and
+                // that the record has not been added already
+                if (HTE_Dscr_Next_p == NULL && HTE_Dscr_Updated_p == NULL)
+                {
+                    // No chain is present for HTE_Dscr_p.
+                    // Link a new HTE descriptor from the free list to
+                    // the found HTE descriptor
+
+                    EIP207_Flow_HTE_Dscr_t * FreeList_Head_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+                    // Check if the overflow bucket offset is a dummy pointer
+                    {
+                        // Read the overflow bucket offset
+                        // (this DMA resource is read-only for the FLUE device)
+                        uint32_t Bucket_ByteOffset =
+                                DMAResource_Read32(
+                                    HT_DMA_Handle,
+                                    (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+                                      EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET);
+
+                        if (Bucket_ByteOffset !=
+                                EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+                            return EIP207_FLOW_INTERNAL_ERROR;
+                    }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+                    FreeList_Head_p =
+                        (EIP207_Flow_HTE_Dscr_t*)HT_Params_p->FreeList_Head_p;
+
+                    // Check if the record can be added
+                    if (FreeList_Head_p == NULL)
+                        // Out of descriptors for overflow buckets
+                        return EIP207_FLOW_OUT_OF_MEMORY_ERROR;
+
+                    slot = 1; // start with slot 1 in the new bucket
+
+                    // Get a free HTE descriptor from the free list head
+                    HTE_Dscr_Next_p =
+                          EIP207_Flow_HTE_Dscr_List_Next_Get(FreeList_Head_p);
+
+                    // Check if the last descriptor is present in the free list
+                    if (HTE_Dscr_Next_p == NULL)
+                    {
+                        HTE_Dscr_Next_p = FreeList_Head_p;
+                        HT_Params_p->FreeList_Head_p = NULL; // List is empty
+                    }
+                    else
+                    {
+                        // Remove the got HTE descriptor from the free list
+                        EIP207_Flow_HTE_Dscr_List_Remove(HTE_Dscr_Next_p);
+                    }
+
+                    // Add the got HTE descriptor to the overflow chain,
+                    // we know that HTE_Dscr_p is the last descriptor
+                    // in the chain
+                    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+                                                       HTE_Dscr_Next_p);
+                    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_Next_p,
+                                                       HTE_Dscr_p);
+
+                    // We add first record to the bucket which HTE descriptor
+                    // just fresh-taken from the free list
+                    HTE_Dscr_Next_p->UsedRecOffsMask =
+                                       EIP207_FLOW_HTE_REC_OFFSET_1;
+
+                    // If flow record is added then write it
+                    if (RecData_p->FR_Data_p != NULL)
+                        EIP207Lib_Flow_FR_Write(
+                                 Rec_Dscr_p->DMA_Handle,
+                                 RecData_p->FR_Data_p,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.Addr -
+                                 HT_Params_p->BaseAddr.Addr,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.Addr,
+                                 RecData_p->FR_Data_p->Xform_DMA_Addr.UpperAddr);
+
+                    // Update the overflow bucket with hash ID and record offset
+                    EIP207Lib_Flow_HB_Record_Add(HT_DMA_Handle,
+                                             HTE_Dscr_Next_p->Bucket_ByteOffset,
+                                             slot,
+                                             Rec_ByteOffset,
+                                             Record_Type,
+                                             RecData_p->HashID_p);
+
+                    // CDS point: after the next write32() operation is done
+                    //            the FLUE HW can find the overflow bucket!
+
+                    // Update bucket offset to the found bucket
+                    // Note: bucket offset can use any address (pointer) type
+                    //       but not NULL!
+                    EIP207Lib_Flow_HB_BuckOffs_Update(
+                                           HT_DMA_Handle,
+                                           HTE_Dscr_p->Bucket_ByteOffset,
+                                           HTE_Dscr_Next_p->Bucket_ByteOffset |
+                                             EIP207_FLOW_RECORD_TR_ADDRESS);
+
+                    // Increment record count for the added record
+                    HTE_Dscr_Next_p->RecordCount++;
+
+                    // Bucket is updated, record is added
+                    if (HTE_Dscr_Updated_p == NULL)
+                        HTE_Dscr_Updated_p = HTE_Dscr_Next_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+                    HTE_Dscr_p = HTE_Dscr_Next_p;
+                    continue; // Validate the entire chain
+#else
+                    break;
+#endif
+                }
+                else // Overflow chain is present for the found HTE_Dscr_p
+                {
+                    // HTE_Dscr_p - last found HTE descriptor in the chain
+                    // HTE_Dscr_Next_p - next HTE descriptor for HTE_Dscr_p
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+                    if (HTE_Dscr_Next_p != NULL)
+                    {
+                        // Consistency checks: next HTE descriptor must be on
+                        //                     the overflow chain
+                        if (!HTE_Dscr_Next_p->fOverflowBucket)
+                            return EIP207_FLOW_INTERNAL_ERROR;
+
+                        // Check if the overflow bucket offset is
+                        // a dummy pointer
+                        {
+                            // Read the overflow bucket offset
+                            // from the previous bucket
+                            uint32_t Bucket_ByteOffset =
+                                DMAResource_Read32(
+                                       HT_DMA_Handle,
+                                       (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+                                       EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET);
+
+                            if (Bucket_ByteOffset !=
+                                (HTE_Dscr_Next_p->Bucket_ByteOffset|
+                                EIP207_FLOW_RECORD_TR_ADDRESS))
+                                return EIP207_FLOW_INTERNAL_ERROR;
+                        }
+                    }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+                    HTE_Dscr_p = HTE_Dscr_Next_p;
+                    continue;
+
+                } // overflow bucket is found
+
+            } // "bucket full" handling is done
+
+        } while(HTE_Dscr_p != NULL);
+
+    } // Record is added to the Hash Table
+
+    // Fill in record descriptor internal data
+    {
+        EIP207_Flow_HTE_Dscr_RecData_t * Rec_DscrData_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+        // Check if the free slot number was found and
+        // the HTE descriptor to update was found
+        if (slot == 0 || HTE_Dscr_Updated_p == NULL)
+            return EIP207_FLOW_INTERNAL_ERROR;
+#endif
+
+        EIP207Lib_Flow_Dscr_InternalData_Set(Rec_Dscr_p);
+        Rec_DscrData_p =
+              (EIP207_Flow_HTE_Dscr_RecData_t*)Rec_Dscr_p->InternalData_p;
+
+        Rec_DscrData_p->Slot         = slot;
+        Rec_DscrData_p->HTE_Dscr_p   = HTE_Dscr_Updated_p;
+
+        if (RecData_p->TR_Data_p != NULL)
+        {
+            if (RecData_p->TR_Data_p->fLarge)
+                Rec_DscrData_p->Type = EIP207_FLOW_REC_TRANSFORM_LARGE;
+            else
+                Rec_DscrData_p->Type = EIP207_FLOW_REC_TRANSFORM_SMALL;
+        }
+        else if (RecData_p->FR_Data_p != NULL)
+            Rec_DscrData_p->Type = EIP207_FLOW_REC_FLOW;
+        else
+            return EIP207_FLOW_INTERNAL_ERROR;
+    }
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_DTL_Record_Remove
+ */
+static EIP207_Flow_Error_t
+EIP207Lib_Flow_DTL_Record_Remove(
+        const Device_Handle_t Device,
+        const unsigned int HashTableId,
+        volatile EIP207_Flow_HT_Params_t * const HT_Params_p,
+        EIP207_Flow_Dscr_t * const Rec_Dscr_p)
+{
+    EIP207_Flow_ID_t HashID;
+    DMAResource_Handle_t HT_DMA_Handle;
+    EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p;
+    EIP207_Flow_HTE_Dscr_RecData_t * Rec_DscrData_p =
+               (EIP207_Flow_HTE_Dscr_RecData_t*)Rec_Dscr_p->InternalData_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+    // Consistency check for the provided TR descriptor
+    if (Rec_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+        return EIP207_FLOW_INTERNAL_ERROR;
+
+    if (Rec_DscrData_p == NULL)
+        return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+    // get the HTE descriptor for the record to remove
+    HTE_Dscr_p = Rec_DscrData_p->HTE_Dscr_p;
+
+    HT_DMA_Handle = HT_Params_p->HT_DMA_Handle;
+
+    ZEROINIT(HashID);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+    // Check record count is sane
+    if (HTE_Dscr_p->RecordCount > EIP207_FLOW_MAX_RECORDS_PER_BUCKET ||
+        HTE_Dscr_p->RecordCount == 0)
+        return EIP207_FLOW_INTERNAL_ERROR;
+
+    // Check the record descriptor slot number
+    if (Rec_DscrData_p->Slot < 1 || Rec_DscrData_p->Slot > 3)
+        return EIP207_FLOW_INTERNAL_ERROR; // Incorrect record slot number
+
+    // Check the record offset calculated from the record descriptor
+    // matches the one on the bucket
+    {
+        uint32_t Rec_ByteOffset2;
+        uint32_t Rec_ByteOffset1 =
+                DMAResource_Read32(HT_DMA_Handle,
+                                   (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+                                     EIP207_FLOW_HB_REC_1_WORD_OFFSET +
+                                       (Rec_DscrData_p->Slot - 1));
+
+        // Clear the bits that specify the record type
+        Rec_ByteOffset1 &= (~EIP207_FLOW_RECORD_ADDRESS_TYPE_BITS);
+
+        // Calculate the record byte offset,
+        // HT_Params_p->BaseAddr.Addr is the base
+        // address of the DMA bank where the record
+        // must have been allocated
+        Rec_ByteOffset2 = Rec_Dscr_p->DMA_Addr.Addr -
+                                            HT_Params_p->BaseAddr.Addr;
+
+        if (Rec_ByteOffset1 != Rec_ByteOffset2)
+            return EIP207_FLOW_INTERNAL_ERROR; // Incorrect record offset
+    }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+    if (HTE_Dscr_p->RecordCount > 1)
+    {
+        // Remove the non-last record from the bucket
+
+        EIP207_Flow_Error_t Flow_Rc;
+
+        // CDS point: record is removed when the next function returns!
+
+        // Update the record offset in the bucket.
+        // Update the Hash ID (optional)
+        EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+                                        HTE_Dscr_p->Bucket_ByteOffset,
+                                        Rec_DscrData_p->Slot,
+                                        &HashID);
+
+        // Mark this record slot as free in the HTE descriptor
+        Flow_Rc = EIP207Lib_Flow_HB_Slot_Put(&HTE_Dscr_p->UsedRecOffsMask,
+                                             Rec_DscrData_p->Slot);
+        if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+            return Flow_Rc;
+
+        // Decrease record count in the HTE descriptor
+        HTE_Dscr_p->RecordCount--;
+    }
+    else // record count = 1, so when removing the record also remove the bucket
+    {
+        // Remove the last record from the removed bucket.
+        // Also remove the bucket from the chain first.
+
+        if (HTE_Dscr_p->fOverflowBucket)
+        {
+            // Remove the last record from the overflow bucket
+
+            EIP207_Flow_HTE_Dscr_t * FreeList_Head_p;
+
+            // Get the neighboring HTE descriptors in the chain
+            EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Prev_p =
+                           EIP207_Flow_HTE_Dscr_List_Prev_Get(HTE_Dscr_p);
+            EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p =
+                           EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+            // Check if the previous HTE descriptor is not NULL,
+            // it may not be NULL for the overflow bucket
+            if (HTE_Dscr_Prev_p == NULL)
+                return EIP207_FLOW_INTERNAL_ERROR;
+#endif
+
+            // CDS point: bucket (and record) is removed when
+            //            the next function returns and the wait loop is done!
+
+            // Remove HTE_Dscr_p bucket from the chain,
+            // make the HTE_Dscr_Prev_p bucket refer to HTE_Dscr_Next_p bucket
+            // Note: bucket offset can use any address (pointer) type
+            //       but not NULL!
+            EIP207Lib_Flow_HB_BuckOffs_Update(
+                                     HT_DMA_Handle,
+                                     HTE_Dscr_Prev_p->Bucket_ByteOffset,
+                                     HTE_Dscr_Next_p ? // the last in chain?
+                                         (HTE_Dscr_Next_p->Bucket_ByteOffset |
+                                             EIP207_FLOW_RECORD_TR_ADDRESS) :
+                                          EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+            // Wait loop: this is to wait for the EIP-207 packet classification
+            //            engine to complete processing using this bucket
+            //            before it can be re-used for another record lookup
+            {
+                unsigned int LoopCount, Value = 1;
+
+                for (LoopCount = 0;
+                     LoopCount < EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT;
+                     LoopCount++)
+                {
+                    // Do some work in the loop
+                    if (LoopCount & BIT_0)
+                        Value <<= 1;
+                    else
+                        Value >>= 1;
+                }
+            } // HB remove wait loop is done!
+
+            // Remove record from the HTE_Dscr_p bucket
+            // which is not in the chain anymore
+            EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+                                            HTE_Dscr_p->Bucket_ByteOffset,
+                                            Rec_DscrData_p->Slot,
+                                            &HashID);
+
+            // Update the bucket offset in the removed from the chain
+            // HTE_Dscr_p bucket
+            EIP207Lib_Flow_HB_BuckOffs_Update(
+                                     HT_DMA_Handle,
+                                     HTE_Dscr_p->Bucket_ByteOffset,
+                                     EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+            // Remove HTE descriptor from the chain
+            EIP207_Flow_HTE_Dscr_List_Remove(HTE_Dscr_p);
+
+            // Add the HTE descriptor to the free list
+            FreeList_Head_p =
+                    (EIP207_Flow_HTE_Dscr_t*)HT_Params_p->FreeList_Head_p;
+
+            // Insert the HTE descriptor at the free list head
+            if (FreeList_Head_p != NULL)
+                EIP207_Flow_HTE_Dscr_List_Insert(FreeList_Head_p, HTE_Dscr_p);
+        }
+        else
+        {
+            // Remove the last record from the HT bucket
+            // Note: the chain may still be present for this HTE_Dscr_p bucket
+
+            // CDS point: record is removed when the next function returns!
+
+            // Update the record offset in the bucket.
+            // Update the Hash ID (optional)
+            EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+                                            HTE_Dscr_p->Bucket_ByteOffset,
+                                            Rec_DscrData_p->Slot,
+                                            &HashID);
+
+            // Wait loop: this is to wait for the EIP-207 packet classification
+            //            engine to complete processing using this bucket
+            //            before it can be re-used for another record lookup
+            {
+                unsigned int LoopCount, Value = 1;
+
+                for (LoopCount = 0;
+                     LoopCount < EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT;
+                     LoopCount++)
+                {
+                    // Do some work in the loop
+                    if (LoopCount & BIT_0)
+                        Value <<= 1;
+                    else
+                        Value >>= 1;
+                }
+            } // HB remove wait loop is done!
+
+            // Mark this record slot as free in the HTE descriptor
+            EIP207Lib_Flow_HB_Slot_Put(&HTE_Dscr_p->UsedRecOffsMask,
+                                       Rec_DscrData_p->Slot);
+        }
+
+        // Update the HTE_Dscr_p record offset mask and record count
+        HTE_Dscr_p->UsedRecOffsMask = 0;
+        HTE_Dscr_p->RecordCount = 0;
+    }
+
+#ifndef EIP207_FLUE_RC_HP
+    // Invalidate lookup result in the FLUEC
+    EIP207_FLUEC_Invalidate(Device,
+                            (uint8_t)HashTableId,
+                            HashID.Word32[0],
+                            HashID.Word32[1],
+                            HashID.Word32[2],
+                            HashID.Word32[3]);
+#else
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(HashTableId);
+#endif
+
+    // Invalidate the internal data of the DTL transform record descriptor
+    Rec_DscrData_p->Slot         = 0;
+    Rec_DscrData_p->HTE_Dscr_p   = NULL;
+    Rec_DscrData_p->Type         = EIP207_FLOW_REC_INVALID;
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Is32bitAddressable
+ */
+static bool
+EIP207Lib_Flow_Is32bitAddressable(
+        const uint32_t BaseAddrLo,
+        const uint32_t BaseAddrHi,
+        const uint32_t AddrLo,
+        const uint32_t AddrHi)
+{
+    if(BaseAddrHi == AddrHi)
+    {
+        if(BaseAddrLo > AddrLo)
+            return false;
+    }
+    else if (BaseAddrHi < AddrHi && (BaseAddrHi == AddrHi + 1))
+    {
+        if(BaseAddrLo <= AddrLo)
+            return false;
+    }
+    else
+        return false;
+
+    return true;
+}
+#endif // EIP207_FLOW_STRICT_ARGS
+
+
+/*****************************************************************************
+ * Generic API functions implemented in DTL-specific way
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_HTE_Dscr_ByteCount_Get(void)
+{
+    return EIP207Lib_Flow_HTE_Dscr_ByteCount_Get();
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_FR_Dscr_ByteCount_Get(void)
+{
+    return sizeof(EIP207_Flow_Rec_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_TR_Dscr_ByteCount_Get(void)
+{
+    return sizeof(EIP207_Flow_Rec_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Record_Dummy_Addr_Get
+ */
+unsigned int
+EIP207_Flow_Record_Dummy_Addr_Get(void)
+{
+    return EIP207_FLOW_RECORD_DUMMY_ADDRESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HashTable_Install
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_HashTable_Install(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_HT_t * HT_p,
+        bool fLookupCached,
+        bool fReset)
+{
+    unsigned int i, EntryCount;
+    Device_Handle_t Device;
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_POINTER(HT_p->HT_DMA_Address_p);
+    EIP207_FLOW_CHECK_POINTER(HT_p->DT_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+    EntryCount = (unsigned int)HT_p->HT_TableSize;
+    EIP207_FLOW_CHECK_INT_ATMOST(EntryCount,
+                                 EIP207_FLOW_HASH_TABLE_ENTRIES_MAX);
+
+    // Convert EIP207_Flow_HashTable_Entry_Count_t to a number
+    EntryCount = EIP207Lib_Flow_TableSize_To_EntryCount(EntryCount);
+    EIP207_FLOW_CHECK_INT_ATMOST(EntryCount, HT_p->DT_EntryCount);
+
+    // Check Flow Hash Table address alignment
+    if (HT_p->HT_DMA_Address_p->Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+        return EIP207_FLOW_ARGUMENT_ERROR;
+
+    // Save the flag that indicates whether the FLUEC must be used
+    // Note: FLUEC is enabled and configured via the Global Control interface
+    TrueIOArea_p->HT_Params[HashTableId].fLookupCached = fLookupCached;
+
+    // Save the host address of the Flow Descriptor Table and its size
+    TrueIOArea_p->HT_Params[HashTableId].DT_p          = HT_p->DT_p;
+    TrueIOArea_p->HT_Params[HashTableId].HT_TableSize  =
+                                            (unsigned int)HT_p->HT_TableSize;
+
+    // Save the DMA resource handle of the Flow Hash Table
+    TrueIOArea_p->HT_Params[HashTableId].HT_DMA_Handle =
+                                                    HT_p->HT_DMA_Handle;
+
+    Device = TrueIOArea_p->Device;
+
+    // Initialize the HT and the DT free list with initial values
+    if (fReset)
+    {
+        EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p =
+                                        (EIP207_Flow_HTE_Dscr_t*)HT_p->DT_p;
+
+        // Initialize the Descriptor Table with initial values
+        memset(HT_p->DT_p,
+               0,
+               HT_p->DT_EntryCount * sizeof(EIP207_Flow_HTE_Dscr_t));
+
+        // Number of HTE descriptors is equal to the number of hash buckets
+        // in the HT plus the number of overflow hash buckets.
+
+        for (i = 0; i < HT_p->DT_EntryCount; i++)
+        {
+            unsigned int j;
+
+            // Initialize with dummy address all the words (j)
+            // in HTE descriptor i
+            for (j = 0; j < EIP207_FLOW_HT_ENTRY_WORD_COUNT; j++)
+                DMAResource_Write32(HT_p->HT_DMA_Handle,
+                                    i * EIP207_FLOW_HT_ENTRY_WORD_COUNT + j,
+                                    EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+            // Add only the HTE descriptors for the overflow hash buckets
+            // to the free list.
+            if (i >= EntryCount)
+            {
+                // Descriptor Table free list initialization,
+                // all the HTE descriptors are added to the free list
+
+                // First overflow HTE descriptor in DT?
+                if (i == EntryCount)
+                {
+                    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p, NULL);
+                    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+                                                       HTE_Dscr_p + 1);
+
+                    // Set the free list head
+                    TrueIOArea_p->HT_Params[HashTableId].FreeList_Head_p =
+                                                                    HTE_Dscr_p;
+                }
+
+                // Last overflow HTE descriptor in DT?
+                if (i == HT_p->DT_EntryCount - 1)
+                {
+                    // First and last overflow HTE descriptor in DT?
+                    if (i != EntryCount)
+                        EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p,
+                                                           HTE_Dscr_p - 1);
+                    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p, NULL);
+                }
+
+                // Non-first and non-last overflow HTE descriptor in DT?
+                if (i != EntryCount && i != (HT_p->DT_EntryCount - 1))
+                {
+                    EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p,
+                                                       HTE_Dscr_p - 1);
+                    EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+                                                       HTE_Dscr_p + 1);
+                }
+
+                // Mark overflow hash buckets
+                HTE_Dscr_p->fOverflowBucket = true;
+            }
+            else
+                // Mark non-overflow hash buckets
+                HTE_Dscr_p->fOverflowBucket = false;
+
+            // Set hash bucket byte offset
+            HTE_Dscr_p->Bucket_ByteOffset = i *
+                                        EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+                                            sizeof(uint32_t);
+
+            HTE_Dscr_p++; // Next HTE descriptor in the DT
+        } // for
+
+        // Perform pre-DMA for the entire HT including the overflow buckets,
+        // both are expected to be in one linear contiguous DMA-safe buffer
+        DMAResource_PreDMA(HT_p->HT_DMA_Handle, 0, 0);
+    }
+
+    // Install the FHT
+    EIP207_FLUE_HASHBASE_LO_WR(Device,
+                               HashTableId,
+                               HT_p->HT_DMA_Address_p->Addr);
+    EIP207_FLUE_HASHBASE_HI_WR(Device,
+                               HashTableId,
+                               HT_p->HT_DMA_Address_p->UpperAddr);
+    EIP207_FLUE_SIZE_UPDATE(Device,
+                            HashTableId,
+                            (uint8_t)HT_p->HT_TableSize);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    if (fReset)
+    {
+        EIP207_Flow_Error_t rv;
+        uint32_t State = TrueIOArea_p->State;
+
+        // Transit to a new state
+        rv = EIP207_Flow_State_Set(
+                (EIP207_Flow_State_t* const)&State,
+                EIP207_FLOW_STATE_ENABLED);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Add
+
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Add(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+        const EIP207_Flow_FR_InputData_t * const FlowInData_p)
+{
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    EIP207_Flow_Record_InputData_t Rec_Data;
+    EIP207_Flow_FR_Data_t FR_Data;
+    EIP207_Flow_Error_t Flow_Rc;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+    EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+    EIP207_FLOW_CHECK_POINTER(FlowInData_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+    // Provided flow record physical DMA address must be addressable by
+    // a 32-bit offset to the Base Address installed via
+    // the EIP207_Flow_RC_BaseAddr_Set() function
+    if(!EIP207Lib_Flow_Is32bitAddressable(
+            TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+            TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+            FR_Dscr_p->DMA_Addr.Addr,
+            FR_Dscr_p->DMA_Addr.UpperAddr))
+        return EIP207_FLOW_ARGUMENT_ERROR;
+
+    // Provided transform record physical DMA address must be addressable by
+    // a 32-bit offset to the Base Address installed via
+    // the EIP207_Flow_RC_BaseAddr_Set() function
+    if(FlowInData_p->Xform_DMA_Addr.Addr != EIP207_FLOW_RECORD_DUMMY_ADDRESS &&
+       !EIP207Lib_Flow_Is32bitAddressable(
+                TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+                TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+                FlowInData_p->Xform_DMA_Addr.Addr,
+                FlowInData_p->Xform_DMA_Addr.UpperAddr))
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+    ZEROINIT(Rec_Data);
+    ZEROINIT(FR_Data);
+
+    FR_Data.Flags           = FlowInData_p->Flags;
+    FR_Data.SW_FR_Reference = FlowInData_p->SW_FR_Reference;
+    FR_Data.Xform_DMA_Addr  = FlowInData_p->Xform_DMA_Addr;
+    FR_Data.fLarge          = FlowInData_p->fLarge;
+
+    Rec_Data.HashID_p       = &FlowInData_p->HashID;
+    Rec_Data.FR_Data_p      = &FR_Data;
+
+    Flow_Rc = EIP207Lib_Flow_DTL_Record_Add(
+                            &TrueIOArea_p->HT_Params[HashTableId],
+                            (EIP207_Flow_Dscr_t*)FR_Dscr_p,
+                            &Rec_Data);
+    if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+        return Flow_Rc;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        EIP207_Flow_Error_t rv;
+        uint32_t State = TrueIOArea_p->State;
+
+        TrueIOArea_p->Rec_InstalledCounter++;
+
+        // Transit to a new state
+        rv = EIP207_Flow_State_Set((EIP207_Flow_State_t* const)&State,
+                                   EIP207_FLOW_STATE_INSTALLED);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_RC_BaseAddr_Set
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_RC_BaseAddr_Set(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_Address_t * const FlowBaseAddr_p,
+        const EIP207_Flow_Address_t * const TransformBaseAddr_p)
+{
+    Device_Handle_t Device;
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+    IDENTIFIER_NOT_USED(TransformBaseAddr_p);
+
+    Device = TrueIOArea_p->Device;
+
+    // Set the common base address for all the records which can be looked up
+    // Note: Standard (legacy) record cache should have
+    //       EIP207_RC_SET_NR_DEFAULT set (which is 0, just one Hash Table);
+    //       High-performance (HP) record cache should have
+    //       HashTableId set
+#ifndef EIP207_FLUE_RC_HP
+    EIP207_RC_BaseAddr_Set(Device,
+                           EIP207_FRC_REG_BASE,
+                           HashTableId, // EIP207_RC_SET_NR_DEFAULT
+                           FlowBaseAddr_p->Addr,
+                           FlowBaseAddr_p->UpperAddr);
+#else
+    EIP207_FLUE_CACHEBASE_LO_WR(Device, HashTableId, FlowBaseAddr_p->Addr);
+    EIP207_FLUE_CACHEBASE_HI_WR(Device, HashTableId, FlowBaseAddr_p->UpperAddr);
+#endif
+
+    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr = FlowBaseAddr_p->Addr;
+    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr =
+                                                    FlowBaseAddr_p->UpperAddr;
+
+    return  EIP207_FLOW_NO_ERROR;
+}
+
+
+/*****************************************************************************
+ * DTL-specific API functions
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_FR_Remove
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_FR_Remove(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p)
+{
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    EIP207_Flow_HTE_Dscr_RecData_t * FR_Data_p;
+    EIP207_Flow_Error_t Flow_Rc;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+    EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+
+    FR_Data_p = (EIP207_Flow_HTE_Dscr_RecData_t*)FR_Dscr_p->InternalData_p;
+
+    EIP207_FLOW_CHECK_POINTER(FR_Data_p);
+    EIP207_FLOW_CHECK_POINTER(FR_Data_p->HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+    // Provided flow record physical DMA address must be addressable by
+    // a 32-bit offset to the Based Address installed via
+    // the EIP207_Flow_RC_BaseAddr_Set() function
+    if(!EIP207Lib_Flow_Is32bitAddressable(
+                TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+                TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+                FR_Dscr_p->DMA_Addr.Addr,
+                FR_Dscr_p->DMA_Addr.UpperAddr))
+        return EIP207_FLOW_ARGUMENT_ERROR;
+
+    if (FR_Data_p->Type != EIP207_FLOW_REC_FLOW)
+        return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+    Flow_Rc = EIP207Lib_Flow_DTL_Record_Remove(
+                          TrueIOArea_p->Device,
+                          HashTableId,
+                          &TrueIOArea_p->HT_Params[HashTableId],
+                          (EIP207_Flow_Dscr_t*)FR_Dscr_p);
+    if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+        return Flow_Rc;
+
+    IDENTIFIER_NOT_USED(FR_Data_p);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        EIP207_Flow_Error_t rv;
+        uint32_t State = TrueIOArea_p->State;
+
+        TrueIOArea_p->Rec_InstalledCounter--;
+
+        // Transit to a new state
+        if (TrueIOArea_p->Rec_InstalledCounter == 0)
+            // Last record is removed
+            rv = EIP207_Flow_State_Set(
+                    (EIP207_Flow_State_t* const)&State,
+                    EIP207_FLOW_STATE_ENABLED);
+        else
+            // Non-last record is removed
+            rv = EIP207_Flow_State_Set(
+                    (EIP207_Flow_State_t* const)&State,
+                    EIP207_FLOW_STATE_INSTALLED);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+#ifndef EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_DTL_TR_Large_WordCount_Get(void)
+{
+    return FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE;
+}
+#endif // !EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Add
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Add(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        const EIP207_Flow_TR_InputData_t * const XformInData_p)
+{
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    EIP207_Flow_Record_InputData_t Rec_Data;
+    EIP207_Flow_TR_Data_t TR_Data;
+    EIP207_Flow_Error_t Flow_Rc;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+    EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+    EIP207_FLOW_CHECK_POINTER(XformInData_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+    // Provided transform record physical DMA address must be addressable by
+    // a 32-bit offset to the Transform Based Address installed via
+    // the EIP207_Flow_RC_BaseAddr_Set() function
+    if(!EIP207Lib_Flow_Is32bitAddressable(
+                    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+                    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+                    TR_Dscr_p->DMA_Addr.Addr,
+                    TR_Dscr_p->DMA_Addr.UpperAddr))
+        return EIP207_FLOW_ARGUMENT_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+    ZEROINIT(Rec_Data);
+    ZEROINIT(TR_Data);
+
+    TR_Data.fLarge     = XformInData_p->fLarge;
+
+    Rec_Data.HashID_p  = &XformInData_p->HashID;
+    Rec_Data.TR_Data_p = &TR_Data;
+
+    Flow_Rc = EIP207Lib_Flow_DTL_Record_Add(
+                            &TrueIOArea_p->HT_Params[HashTableId],
+                            (EIP207_Flow_Dscr_t*)TR_Dscr_p,
+                            &Rec_Data);
+    if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+        return Flow_Rc;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        EIP207_Flow_Error_t rv;
+        uint32_t State = TrueIOArea_p->State;
+
+        TrueIOArea_p->Rec_InstalledCounter++;
+
+        // Transit to a new state
+        rv = EIP207_Flow_State_Set((EIP207_Flow_State_t* const)&State,
+                                   EIP207_FLOW_STATE_INSTALLED);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+#ifndef EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Large_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        EIP207_Flow_TR_OutputData_t * const XformData_p)
+{
+    EIP207_Flow_Error_t rv;
+    uint32_t Value32, SeqNrWordOffset;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+    EIP207_FLOW_CHECK_POINTER(XformData_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+    IDENTIFIER_NOT_USED(IOArea_p);
+    IDENTIFIER_NOT_USED(HashTableId);
+
+    // Prepare the transform record for reading
+    DMAResource_PostDMA(TR_Dscr_p->DMA_Handle, 0, 0);
+
+    // Read the transform record data
+
+    // Recent record Packets Counter
+    XformData_p->PacketsCounter =
+            DMAResource_Read32(
+                    TR_Dscr_p->DMA_Handle,
+                    FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET_LARGE);
+
+    // Read Token Context Instruction word
+    Value32 =
+        DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+                FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET_LARGE);
+
+    // Extract the Sequence Number word offset from the read value
+    FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read(Value32, &SeqNrWordOffset);
+
+    // Read the sequence number
+    XformData_p->SequenceNumber =
+            DMAResource_Read32(TR_Dscr_p->DMA_Handle, SeqNrWordOffset);
+
+    // Recent record time stamp
+    rv = EIP207_Flow_Internal_Read64(
+                   TR_Dscr_p->DMA_Handle,
+                   FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET_LARGE,
+                   FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET_LARGE,
+                   &XformData_p->LastTimeLo,
+                   &XformData_p->LastTimeHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+    // Recent record Octets Counter
+    rv = EIP207_Flow_Internal_Read64(
+                   TR_Dscr_p->DMA_Handle,
+                   FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET_LARGE,
+                   FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET_LARGE,
+                   &XformData_p->OctetsCounterLo,
+                   &XformData_p->OctetsCounterHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+    return EIP207_FLOW_NO_ERROR;
+}
+#endif // !EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Remove
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Remove(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p)
+{
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    EIP207_Flow_HTE_Dscr_RecData_t * TR_Data_p;
+    EIP207_Flow_Error_t Flow_Rc;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+    EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+
+    TR_Data_p = (EIP207_Flow_HTE_Dscr_RecData_t*)TR_Dscr_p->InternalData_p;
+
+    EIP207_FLOW_CHECK_POINTER(TR_Data_p);
+    EIP207_FLOW_CHECK_POINTER(TR_Data_p->HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+    // Provided transform record physical DMA address must be addressable by
+    // a 32-bit offset to the Transform Based Address installed via
+    // the EIP207_Flow_RC_BaseAddr_Set() function
+    if(!EIP207Lib_Flow_Is32bitAddressable(
+                    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+                    TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+                    TR_Dscr_p->DMA_Addr.Addr,
+                    TR_Dscr_p->DMA_Addr.UpperAddr))
+        return EIP207_FLOW_ARGUMENT_ERROR;
+
+    if (TR_Data_p->Type != EIP207_FLOW_REC_TRANSFORM_SMALL &&
+        TR_Data_p->Type != EIP207_FLOW_REC_TRANSFORM_LARGE)
+        return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+    Flow_Rc = EIP207Lib_Flow_DTL_Record_Remove(
+                          TrueIOArea_p->Device,
+                          HashTableId,
+                          &TrueIOArea_p->HT_Params[HashTableId],
+                          (EIP207_Flow_Dscr_t*)TR_Dscr_p);
+    if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+        return Flow_Rc;
+
+    IDENTIFIER_NOT_USED(TR_Data_p);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        EIP207_Flow_Error_t rv;
+        uint32_t State = TrueIOArea_p->State;
+
+        TrueIOArea_p->Rec_InstalledCounter--;
+
+        // Transit to a new state
+        if (TrueIOArea_p->Rec_InstalledCounter == 0)
+            // Last record is removed
+            rv = EIP207_Flow_State_Set(
+                    (EIP207_Flow_State_t* const)&State,
+                    EIP207_FLOW_STATE_ENABLED);
+        else
+            // Non-last record is removed
+            rv = EIP207_Flow_State_Set(
+                    (EIP207_Flow_State_t* const)&State,
+                    EIP207_FLOW_STATE_INSTALLED);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/* end of file eip207_flow_dtl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c
new file mode 100644
index 0000000..cd3ecbd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c
@@ -0,0 +1,512 @@
+/* eip207_flow_generic.c
+ *
+ * Partial EIP-207 Flow Control Generic API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                       // ZEROINIT, memset, memcpy
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"
+#include "dmares_rw.h"
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_level0.h"         // EIP-207 Level 0 macros
+#include "eip207_flow_internal.h"
+
+// EIP-207 Firmware API
+#include "firmware_eip207_api_flow_cs.h" // Classification API: Flow Control
+#include "firmware_eip207_api_cs.h"      // Classification API: General
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Detect
+ *
+ * Checks the presence of EIP-207c hardware. Returns true when found.
+ */
+static bool
+EIP207Lib_Flow_Detect(
+        const Device_Handle_t Device)
+{
+    uint32_t Value;
+
+    Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_VERSION);
+    if (!EIP207_FLUE_SIGNATURE_MATCH( Value ))
+        return false;
+
+    // read-write test one of the registers
+
+    // Set MASK_31_BITS bits of the EIP207_FLUE_REG_HASHBASE_LO register
+    EIP207_Flow_Write32( Device,
+                         EIP207_FLUE_FHT_REG_HASHBASE_LO(0),
+                         ~MASK_2_BITS);
+    Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0));
+    if ((Value) != ~MASK_2_BITS)
+        return false;
+
+    // Clear MASK_31_BITS bits of the EIP207_FLUE_REG_HASHBASE_LO register
+    EIP207_Flow_Write32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0), 0);
+    Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0));
+    if (Value != 0)
+       return false;
+
+    return true;
+}
+
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_State_Set
+ *
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_State_Set(
+        EIP207_Flow_State_t * const CurrentState,
+        const EIP207_Flow_State_t NewState)
+{
+    switch(*CurrentState)
+    {
+        case EIP207_FLOW_STATE_INITIALIZED:
+            switch(NewState)
+            {
+                case EIP207_FLOW_STATE_ENABLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP207_FLOW_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP207_FLOW_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP207_FLOW_STATE_ENABLED:
+            switch(NewState)
+            {
+                case EIP207_FLOW_STATE_INSTALLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP207_FLOW_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP207_FLOW_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP207_FLOW_STATE_INSTALLED:
+            switch(NewState)
+            {
+                case EIP207_FLOW_STATE_INSTALLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP207_FLOW_STATE_ENABLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP207_FLOW_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP207_FLOW_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        default:
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+
+    return EIP207_FLOW_NO_ERROR;
+}
+#endif // EIP207_FLOW_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_IOArea_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_IOArea_ByteCount_Get(void)
+{
+    return sizeof(EIP207_Flow_True_IOArea_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HT_Entry_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_HT_Entry_WordCount_Get(void)
+{
+    return EIP207_FLOW_HT_ENTRY_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Init
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Init(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+
+    // Detect presence of EIP-207c HW hardware
+    if (!EIP207Lib_Flow_Detect(Device))
+        return EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR;
+
+    // Initialize the IO Area
+    TrueIOArea_p->Device = Device;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        TrueIOArea_p->Rec_InstalledCounter = 0;
+
+        TrueIOArea_p->State = (uint32_t)EIP207_FLOW_STATE_INITIALIZED;
+    }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_ID_Compute
+ *
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_ID_Compute(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_SelectorParams_t * const SelectorParams_p,
+        EIP207_Flow_ID_t * const FlowID)
+{
+    uint32_t h1, h2, h3, h4;
+    uint32_t w;
+    const uint32_t * p;
+    uint32_t count, data [FIRMWARE_EIP207_CS_FLOW_HASH_ID_INPUT_WORD_COUNT];
+    Device_Handle_t Device;
+    FIRMWARE_EIP207_CS_Flow_SelectorParams_t Selectors;
+    volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_POINTER(SelectorParams_p);
+    EIP207_FLOW_CHECK_POINTER(FlowID);
+
+    Device = TrueIOArea_p->Device;
+
+    // Read the IV from the flow hash engine in the classification engine
+    // The IV must have been already installed in the flow hash engine
+    // via the Global Classification Control API
+    EIP207_FHASH_IV_RD(Device, HashTableId, &h1, &h2, &h3, &h4);
+
+    // Install the selectors for the flow hash ID calculation
+    ZEROINIT(Selectors);
+    Selectors.Flags   = SelectorParams_p->Flags;
+    Selectors.DstIp_p = SelectorParams_p->DstIp_p;
+    Selectors.DstPort = SelectorParams_p->DstPort;
+    Selectors.IpProto = SelectorParams_p->IpProto;
+    Selectors.SPI     = SelectorParams_p->SPI;
+#ifdef FIRMWARE_EIP207_CS_FLOW_DTLS_SUPPORTED
+    Selectors.Epoch     = SelectorParams_p->Epoch;
+#endif
+    Selectors.SrcIp_p = SelectorParams_p->SrcIp_p;
+    Selectors.SrcPort = SelectorParams_p->SrcPort;
+    FIRMWARE_EIP207_CS_Flow_Selectors_Reorder(&Selectors, data, &count);
+
+    p = data;
+
+    while (p < &data[count - 3])
+    {
+        w = *p++;
+        h2 ^= w;
+        h1 += w;
+        h1 += h1 << 10;
+        h1 ^= h1 >> 6;
+
+        w = *p++;
+        h3 ^= w;
+        h1 += w;
+        h1 += h1 << 10;
+        h1 ^= h1 >> 6;
+
+        w = *p++;
+        h4 ^= w;
+        h1 += w;
+        h1 += h1 << 10;
+        h1 ^= h1 >> 6;
+
+        /* Mixing step for the 96 bits in h2-h4.  The code comes from a
+           hash table lookup function by Robert J. Jenkins, and has been
+           presented on numerous web pages and in a Dr. Dobbs Journal
+           sometimes in late 90's.
+
+           h1 is computed according to the one-at-a-time hash function,
+           presented in the same article. */
+        h2 -= h3;  h2 -= h4;  h2 ^= h4 >> 13;
+        h3 -= h4;  h3 -= h2;  h3 ^= h2 << 8;
+        h4 -= h2;  h4 -= h3;  h4 ^= h3 >> 13;
+        h2 -= h3;  h2 -= h4;  h2 ^= h4 >> 12;
+        h3 -= h4;  h3 -= h2;  h3 ^= h2 << 16;
+        h4 -= h2;  h4 -= h3;  h4 ^= h3 >> 5;
+        h2 -= h3;  h2 -= h4;  h2 ^= h4 >> 3;
+        h3 -= h4;  h3 -= h2;  h3 ^= h2 << 10;
+        h4 -= h2;  h4 -= h3;  h4 ^= h3 >> 15;
+    } // while
+
+    w = *p++;
+    h1 += w;
+    h1 += h1 << 10;
+    h1 ^= h1 >> 6;
+    h2 ^= w;
+
+    if (p < data + count)
+    {
+        w = *p++;
+        h1 += w;
+        h1 += h1 << 10;
+        h1 ^= h1 >> 6;
+        h3 ^= w;
+
+        if (p < data + count)
+        {
+            w = *p++;
+            h1 += w;
+            h1 += h1 << 10;
+            h1 ^= h1 >> 6;
+            h4 ^= w;
+        }
+    }
+
+    FlowID->Word32[0] = h1;
+    FlowID->Word32[1] = h2;
+    FlowID->Word32[2] = h3;
+    FlowID->Word32[3] = h4;
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_FR_WordCount_Get(void)
+{
+    return FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+        EIP207_Flow_FR_OutputData_t * const FlowData_p)
+{
+    EIP207_Flow_Error_t rv;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+    EIP207_FLOW_CHECK_POINTER(FlowData_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+    IDENTIFIER_NOT_USED(HashTableId);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+    // Consistency check for the provided flow descriptor
+    if (FR_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+        return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+    // Prepare the flow record for reading
+    DMAResource_PostDMA(FR_Dscr_p->DMA_Handle, 0, 0);
+
+    // Read the flow record data
+
+    // Recent record Packets Counter
+    FlowData_p->PacketsCounter =
+            DMAResource_Read32(FR_Dscr_p->DMA_Handle,
+                               FIRMWARE_EIP207_CS_FLOW_FR_STAT_PKT_WORD_OFFSET);
+
+    // Recent record time stamp
+    rv = EIP207_Flow_Internal_Read64(
+                       FR_Dscr_p->DMA_Handle,
+                       FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_LO_WORD_OFFSET,
+                       FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_HI_WORD_OFFSET,
+                       &FlowData_p->LastTimeLo,
+                       &FlowData_p->LastTimeHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+    // Recent record Octets Counter
+    rv = EIP207_Flow_Internal_Read64(
+                       FR_Dscr_p->DMA_Handle,
+                       FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_LO_WORD_OFFSET,
+                       FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_HI_WORD_OFFSET,
+                       &FlowData_p->OctetsCounterLo,
+                       &FlowData_p->OctetsCounterHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+    {
+        volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+        uint32_t State = TrueIOArea_p->State;
+
+        // Remain in the current state
+        rv = EIP207_Flow_State_Set(
+                (EIP207_Flow_State_t* const)&State,
+                (EIP207_Flow_State_t)TrueIOArea_p->State);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_FLOW_NO_ERROR)
+            return EIP207_FLOW_ILLEGAL_IN_STATE;
+    }
+#else
+    IDENTIFIER_NOT_USED(IOArea_p);
+#endif // EIP207_FLOW_DEBUG_FSM
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_TR_WordCount_Get(void)
+{
+    return FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_TR_Read(
+        EIP207_Flow_IOArea_t * const IOArea_p,
+        const unsigned int HashTableId,
+        const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        EIP207_Flow_TR_OutputData_t * const XformData_p)
+{
+    EIP207_Flow_Error_t rv;
+    uint32_t Value32, SeqNrWordOffset;
+
+    EIP207_FLOW_CHECK_POINTER(IOArea_p);
+    EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+    EIP207_FLOW_CHECK_POINTER(XformData_p);
+    EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+                                 EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+    IDENTIFIER_NOT_USED(IOArea_p);
+    IDENTIFIER_NOT_USED(HashTableId);
+
+    // Prepare the transform record for reading
+    DMAResource_PostDMA(TR_Dscr_p->DMA_Handle, 0, 0);
+
+    // Read the transform record data
+
+    // Recent record Packets Counter
+    XformData_p->PacketsCounter =
+            DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+                               FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET);
+
+    // Read Token Context Instruction word
+    Value32 =
+        DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+                           FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET);
+
+    // Extract the Sequence Number word offset from the read value
+    FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read(Value32, &SeqNrWordOffset);
+
+    // Read the sequence number
+    XformData_p->SequenceNumber =
+            DMAResource_Read32(TR_Dscr_p->DMA_Handle, SeqNrWordOffset);
+
+    // Recent record time stamp
+    rv = EIP207_Flow_Internal_Read64(
+                   TR_Dscr_p->DMA_Handle,
+                   FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET,
+                   FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET,
+                   &XformData_p->LastTimeLo,
+                   &XformData_p->LastTimeHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+    // Recent record Octets Counter
+    rv = EIP207_Flow_Internal_Read64(
+                   TR_Dscr_p->DMA_Handle,
+                   FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET,
+                   FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET,
+                   &XformData_p->OctetsCounterLo,
+                   &XformData_p->OctetsCounterHi);
+    if (rv != EIP207_FLOW_NO_ERROR)
+        return rv;
+
+    return EIP207_FLOW_NO_ERROR;
+}
+
+
+/* end of file eip207_flow_generic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c
new file mode 100644
index 0000000..1b61461
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c
@@ -0,0 +1,95 @@
+/* eip207_flow_internal.c
+ *
+ *  EIP-207 Flow Control Internal interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_internal.h"
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "eip207_flow_level0.h"         // EIP-207 Level 0 macros
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // BIT definitions, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_rw.h"          // DMAResource_Write32()/_Read32()/_PreDMA()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Internal_Read64
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Internal_Read64(
+        const DMAResource_Handle_t Handle,
+        const unsigned int Value64_WordOffsetLo,
+        const unsigned int Value64_WordOffsetHi,
+        uint32_t * const Value64_Lo,
+        uint32_t * const Value64_Hi)
+{
+    uint32_t Value32;
+    unsigned int i;
+
+    for (i = 0; i < EIP207_FLOW_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS; i++)
+    {
+        Value32     = DMAResource_Read32(Handle, Value64_WordOffsetHi);
+        *Value64_Lo = DMAResource_Read32(Handle, Value64_WordOffsetLo);
+
+        // Prepare the flow record for reading
+        DMAResource_PostDMA(Handle, 0, 0);
+
+        *Value64_Hi = DMAResource_Read32(Handle, Value64_WordOffsetHi);
+
+        if (Value32 == (*Value64_Hi))
+            return EIP207_FLOW_NO_ERROR;
+    }
+
+    return EIP207_FLOW_INTERNAL_ERROR;
+}
+
+
+/* end of file eip207_flow_hte_dscr_dtl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c
new file mode 100644
index 0000000..1074b7a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c
@@ -0,0 +1,177 @@
+/* eip207_ice.c
+ *
+ * EIP-207s Flow Look-Up Engine (FLUE) interface implementation
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207s Flow Look-Up Engine (FLUE) interface
+#include "eip207_flue.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLUE_3ENTRY_LOOKUP_MODE          1
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Init
+ */
+void
+EIP207_FLUE_Init(
+        const Device_Handle_t Device,
+        const unsigned int HashTableId,
+        const EIP207_Global_FLUEConfig_t * const FLUEConf_p,
+        const bool fARC4Present,
+        const bool fLookupCachePresent)
+{
+    // Configure hash tables
+    EIP207_FLUE_CONFIG_WR(Device,
+                          HashTableId, // Hash Table ID
+                          HashTableId, // Function,
+                                       // set it equal to hash table id
+                          0,           // Generation
+                          true,        // Table enable
+                          true);       // Access enable
+
+    // Use Hash table 0 parameters, they must be the same for all the tables!
+    // Initialize FLUE with EIP-207 Firmware Classification API parameters
+    EIP207_FLUE_OFFSET_WR(Device,
+                          FLUEConf_p->HashTable[HashTableId].fPrefetchXform,
+                          fLookupCachePresent ?
+                              FLUEConf_p->HashTable[HashTableId].fLookupCached :
+                              false,
+                          FIRMWARE_EIP207_CS_XFORM_RECORD_WORD_OFFSET);
+
+    // Use Hash table 0 parameters, they must be the same for all the tables!
+    // Check if ARC4 Record Cache is available
+    if ( fARC4Present )
+    {
+        EIP207_FLUE_ARC4_OFFSET_WR(
+                          Device,
+                          FLUEConf_p->HashTable[HashTableId].fPrefetchARC4State,
+                          EIP207_GLOBAL_FLUE_LOOKUP_MODE,
+                          FIRMWARE_EIP207_CS_ARC4_RECORD_WORD_OFFSET);
+    }
+#if EIP207_GLOBAL_FLUE_LOOKUP_MODE == EIP207_FLUE_3ENTRY_LOOKUP_MODE
+    else
+    {
+        EIP207_FLUE_ARC4_OFFSET_WR(Device,
+                                   HashTableId,
+                                   EIP207_GLOBAL_FLUE_LOOKUP_MODE,
+                                   0);
+    }
+#endif // EIP207_GLOBAL_FLUE_LOOKUP_MODE == EIP207_FLUE_1ENTRY_LOOKUP_MODE
+
+#ifdef EIP207_FLUE_HAVE_VIRTUALIZATION
+    // Virtualisation support present, initialize the lookup table.
+    // All interfaces refer to Table # 0.
+    {
+        unsigned int i;
+        unsigned int c;
+        unsigned int idx0,idx1,idx2,idx3;
+
+        c = FLUEConf_p->InterfacesCount;
+        if (c > EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE)
+            c = EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE;
+
+        for (i = 0; i < c; i += 4)
+        {
+            idx0 = FLUEConf_p->InterfaceIndex[i];
+
+            if (i + 1 < c)
+                idx1 = FLUEConf_p->InterfaceIndex[i + 1];
+            else
+                idx1 = 0;
+
+            if (i + 2 < c)
+                idx2 = FLUEConf_p->InterfaceIndex[i + 2];
+            else
+                idx2 = 0;
+
+            if (i + 3 < c)
+                idx3 = FLUEConf_p->InterfaceIndex[i + 3];
+            else
+                idx3 = 0;
+
+            EIP207_FLUE_IFC_LUT_WR(Device,
+                                   i / 4,
+                                   idx0, idx1, idx2, idx3);
+        }
+    }
+#endif
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Status_Get
+ */
+void
+EIP207_FLUE_Status_Get(
+        const Device_Handle_t Device,
+        EIP207_Global_FLUE_Status_t * const FLUE_Status_p)
+{
+    IDENTIFIER_NOT_USED(Device);
+
+    FLUE_Status_p->Error1 = 0;
+    FLUE_Status_p->Error2 = 0;
+
+    return;
+}
+
+
+/* end of file eip207_flue.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c
new file mode 100644
index 0000000..82f04ac
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c
@@ -0,0 +1,77 @@
+/* eip207_fluec.c
+ *
+ * EIP-207 Flow Look-Up Engine Cache (FLUEC) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207s Flow Look-Up Engine Cache (FLUEC) interface
+#include "eip207_fluec.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint8_t, uint32_t,
+                                        // IDENTIFIER_NOT_USED
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUEC_Invalidate
+ */
+void
+EIP207_FLUEC_Invalidate(
+        const Device_Handle_t Device,
+        const uint8_t InvTable,
+        const uint32_t FlowID_W0,
+        const uint32_t FlowID_W1,
+        const uint32_t FlowID_W2,
+        const uint32_t FlowID_W3)
+{
+    // Not implemented
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(InvTable);
+    IDENTIFIER_NOT_USED(FlowID_W0);
+    IDENTIFIER_NOT_USED(FlowID_W1);
+    IDENTIFIER_NOT_USED(FlowID_W2);
+    IDENTIFIER_NOT_USED(FlowID_W3);
+}
+
+
+/* end of file eip207_fluec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c
new file mode 100644
index 0000000..41586a8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c
@@ -0,0 +1,690 @@
+/* eip207_global_init.c
+ *
+ * EIP-207 Global Control Driver Library
+ * Initialization and status retrieval Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Global Control API
+#include "eip207_global_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                       // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// EIP-207s Record Cache (RC) internal interface
+#include "eip207_rc_internal.h"
+
+// EIP-207c Input Classification Engine (ICE) interface
+#include "eip207_ice.h"
+
+// EIP-207c Output Classification Engine (OCE) interface
+#include "eip207_oce.h"
+
+// EIP-207s Flow Look-Up Engine (FLUE) interface
+#include "eip207_flue.h"
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// EIP-207s Flow Look-Up Engine Cache (FLUEC) Level0 interface
+#include "eip207_fluec_level0.h"
+
+// EIP-207c Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // Classification API: General
+
+// EIP-207c Firmware Download API
+#include "firmware_eip207_api_dwld.h"   // Classification API: FW download
+
+// EIP97 Global init API
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum number of EIP-207c Classification Engines that should be used
+// Should not exceed the number of engines physically available
+#ifndef EIP207_GLOBAL_MAX_NOF_CE_TO_USE
+#error "EIP207_GLOBAL_MAX_NOF_CE_TO_USE is not defined"
+#endif
+
+// Maximum number of flow hash tables that should be used
+#ifndef EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#error "EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE is not defined"
+#endif
+
+// Default Classification Engine number
+#define CE_DEFAULT_NR                                   0
+
+#if (CE_DEFAULT_NR >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+#error "Error: CE_DEFAULT_NR must be less than EIP207_GLOBAL_MAX_NOF_CE_TO_USE"
+#endif
+
+// Size of the ARC4 State Record in 32-bit words
+#define EIP207_CS_ARC4RC_RECORD_WORD_COUNT              64
+
+#ifndef FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT
+#define FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT     64
+#endif
+
+// I/O Area, used internally
+typedef struct
+{
+    Device_Handle_t Device;
+    uint32_t State;
+} EIP207_True_IOArea_t;
+
+#define IOAREA(_p) ((volatile EIP207_True_IOArea_t *)_p)
+
+#ifdef EIP207_GLOBAL_STRICT_ARGS
+#define EIP207_GLOBAL_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+#else
+/* EIP207_GLOBAL_STRICT_ARGS undefined */
+#define EIP207_GLOBAL_CHECK_POINTER(_p)
+#define EIP207_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP207_GLOBAL_CHECK_INT_ATLEAST(_i, _min)
+#define EIP207_GLOBAL_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP207_GLOBAL_STRICT_ARGS */
+
+#define TEST_SIZEOF(type, size) \
+    extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP207_True_IOArea_t, EIP207_GLOBAL_IOAREA_REQUIRED_SIZE);
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+// EIP-207 Global Control API States
+typedef enum
+{
+    EIP207_GLOBAL_STATE_INITIALIZED  = 5,
+    EIP207_GLOBAL_STATE_FATAL_ERROR  = 7,
+    EIP207_GLOBAL_STATE_RC_ENABLED   = 8,
+    EIP207_GLOBAL_STATE_FW_LOADED    = 9
+} EIP207_Global_State_t;
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Detect
+ *
+ * Checks the presence of EIP-207 hardware. Returns true when found.
+ */
+static bool
+EIP207Lib_Detect(
+        const Device_Handle_t Device,
+        const unsigned int CEnr)
+{
+    uint32_t Value;
+
+    IDENTIFIER_NOT_USED(CEnr);
+
+    Value = EIP207_Read32(Device, EIP207_CS_REG_VERSION);
+    if (!EIP207_CS_SIGNATURE_MATCH( Value ))
+        return false;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_HWRevision_Get
+ */
+static void
+EIP207Lib_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP207_Options_t * const Options_p,
+        EIP207_Version_t * const Version_p)
+{
+    EIP207_CS_VERSION_RD(
+                      Device,
+                      &Version_p->EipNumber,
+                      &Version_p->ComplmtEipNumber,
+                      &Version_p->HWPatchLevel,
+                      &Version_p->MinHWRevision,
+                      &Version_p->MajHWRevision);
+
+    EIP207_CS_OPTIONS_RD(Device,
+                         &Options_p->NofLookupTables,
+                         &Options_p->fLookupCached,
+                         &Options_p->NofLookupClients,
+                         &Options_p->fCombinedTRC_ARC4,
+                         &Options_p->fCombinedFRC_ARC4,
+                         &Options_p->fARC4Present,
+                         &Options_p->NofARC4_Clients,
+                         &Options_p->fCombinedFRC_TRC,
+                         &Options_p->NofTRC_Clients,
+                         &Options_p->NofFRC_Clients,
+                         &Options_p->NofCacheSets);
+}
+
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Global_State_Set
+ *
+ */
+static EIP207_Global_Error_t
+EIP207Lib_Global_State_Set(
+        EIP207_Global_State_t * const CurrentState,
+        const EIP207_Global_State_t NewState)
+{
+    switch(*CurrentState)
+    {
+        case EIP207_GLOBAL_STATE_INITIALIZED:
+            switch(NewState)
+            {
+                case EIP207_GLOBAL_STATE_RC_ENABLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP207_GLOBAL_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+         case EIP207_GLOBAL_STATE_RC_ENABLED:
+            switch(NewState)
+            {
+                case EIP207_GLOBAL_STATE_FW_LOADED:
+                   *CurrentState = NewState;
+                   break;
+                case EIP207_GLOBAL_STATE_FATAL_ERROR:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        default:
+            return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+    }
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Init
+ */
+EIP207_Global_Error_t
+EIP207_Global_Init(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device,
+        EIP207_Global_CacheConfig_t * const CacheConf_p,
+        const EIP207_Global_FLUEConfig_t * const FLUEConf_p)
+{
+    unsigned int FLUE_NofLookupTables;
+    EIP207_Global_Capabilities_t Capabilities;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    unsigned int i;
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP207_GLOBAL_CHECK_POINTER(CacheConf_p);
+    EIP207_GLOBAL_CHECK_POINTER(FLUEConf_p);
+
+    // Detect presence of EIP-207 HW hardware
+    if (!EIP207Lib_Detect(Device, CE_DEFAULT_NR))
+        return EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    // Initialize the IO Area
+    TrueIOArea_p->Device = Device;
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+    TrueIOArea_p->State = (uint32_t)EIP207_GLOBAL_STATE_INITIALIZED;
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+    ZEROINIT(Capabilities);
+
+    EIP207Lib_HWRevision_Get(Device,
+                             &Capabilities.EIP207_Options,
+                             &Capabilities.EIP207_Version);
+
+    FLUE_NofLookupTables = Capabilities.EIP207_Options.NofLookupTables;
+
+    // 0 hash tables has a special meaning for the EIP-207 FLUE HW
+    if (FLUE_NofLookupTables == 0)
+        FLUE_NofLookupTables = EIP207_GLOBAL_MAX_HW_NOF_FLOW_HASH_TABLES;
+
+    // Check actual configuration HW against capabilities
+    // Number of configured cache sets and hash tables
+    if ((Capabilities.EIP207_Options.NofCacheSets <
+            EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE) ||
+        (FLUE_NofLookupTables <
+            EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE)  ||
+        (FLUEConf_p->HashTablesCount >
+            EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE))
+        return EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    // Configure EIP-207 Classification Engine
+
+    // Initialize Record Caches
+    {
+        EIP207_Global_Error_t rv;
+
+        // Initialize Flow Record Cache
+#ifndef EIP207_GLOBAL_FRC_DISABLE
+        if ((EIP97_SupportedFuncs_Get() & BIT_3) != 0)
+        {
+            for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+            {
+                CacheConf_p->FRC[i].DataWordCount = EIP207_FRC_RAM_WORD_COUNT;
+                CacheConf_p->FRC[i].AdminWordCount =
+                    EIP207_FRC_ADMIN_RAM_WORD_COUNT;
+            }
+
+            rv = EIP207_RC_Internal_Init(
+                Device,
+                EIP207_RC_INTERNAL_NOT_COMBINED,
+                EIP207_FRC_REG_BASE,
+                CacheConf_p->FRC,
+                FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT);
+            if (rv != EIP207_GLOBAL_NO_ERROR)
+                return rv;
+        }
+#endif // EIP207_GLOBAL_FRC_DISABLE
+        for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+        {
+            CacheConf_p->TRC[i].DataWordCount = EIP207_TRC_RAM_WORD_COUNT;
+            CacheConf_p->TRC[i].AdminWordCount =
+                EIP207_TRC_ADMIN_RAM_WORD_COUNT;
+        }
+
+        // Initialize Transform Record Cache
+        rv = EIP207_RC_Internal_Init(
+                 Device,
+                 Capabilities.EIP207_Options.fCombinedFRC_TRC ?
+                         EIP207_RC_INTERNAL_FRC_TRC_COMBINED :
+                                EIP207_RC_INTERNAL_NOT_COMBINED,
+                 EIP207_TRC_REG_BASE,
+                 CacheConf_p->TRC,
+                 FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT);
+        if (rv != EIP207_GLOBAL_NO_ERROR)
+            return rv;
+
+        // Check if ARC4 Record Cache is available
+        if ( Capabilities.EIP207_Options.fARC4Present )
+        {
+            for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+            {
+                CacheConf_p->ARC4[i].DataWordCount =
+                    EIP207_ARC4RC_RAM_WORD_COUNT;
+                CacheConf_p->ARC4[i].AdminWordCount =
+                    EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT;
+            }
+            // Initialize ARC4 Record Cache
+            rv = EIP207_RC_Internal_Init(
+                    Device,
+                    Capabilities.EIP207_Options.fCombinedFRC_ARC4 ?
+                        EIP207_RC_INTERNAL_FRC_ARC4_COMBINED :
+                    (Capabilities.EIP207_Options.fCombinedTRC_ARC4 ?
+                          EIP207_RC_INTERNAL_TRC_ARC4_COMBINED :
+                                    EIP207_RC_INTERNAL_NOT_COMBINED),
+                    EIP207_ARC4RC_REG_BASE,
+                    CacheConf_p->ARC4,
+                    FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT);
+            if (rv != EIP207_GLOBAL_NO_ERROR)
+                return rv;
+        }
+    }
+
+    // Initialize Flow Hash Engine, set IV values
+    EIP207_FHASH_IV_WR(Device,
+                       FLUEConf_p->IV.IV_Word32[0],
+                       FLUEConf_p->IV.IV_Word32[1],
+                       FLUEConf_p->IV.IV_Word32[2],
+                       FLUEConf_p->IV.IV_Word32[3]);
+
+    // Initialize FLUE Hash Tables
+    {
+        unsigned int i;
+
+        for (i = 0; i < FLUEConf_p->HashTablesCount; i++)
+            EIP207_FLUE_Init(Device,
+                             i,
+                             FLUEConf_p,
+                             Capabilities.EIP207_Options.fARC4Present,
+                             Capabilities.EIP207_Options.fLookupCached);
+    }
+
+    // Initialize optional FLUE Cache
+    if (Capabilities.EIP207_Options.fLookupCached)
+    {
+        EIP207_FLUEC_CTRL_WR(Device,
+                             false,        // Disable cache RAM access
+                             FLUEConf_p->fDelayMemXS,
+                             EIP207_FLUEC_TABLE_SIZE,
+                             EIP207_FLUEC_GROUP_SIZE,
+                             FLUEConf_p->CacheChain);  // Cache chain
+    }
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+        {
+            EIP207_Global_Error_t rv;
+            uint32_t State = TrueIOArea_p->State;
+
+            // Transit to a new state
+            rv = EIP207Lib_Global_State_Set(
+                    (EIP207_Global_State_t* const)&State,
+                    EIP207_GLOBAL_STATE_RC_ENABLED);
+
+            TrueIOArea_p->State = State;
+
+            if (rv != EIP207_GLOBAL_NO_ERROR)
+                return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+        }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_Global_Firmware_Load(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const IPUE_Firmware_p,
+        EIP207_Firmware_t * const IFPP_Firmware_p,
+        EIP207_Firmware_t * const OPUE_Firmware_p,
+        EIP207_Firmware_t * const OFPP_Firmware_p)
+{
+    EIP207_Global_Error_t EIP207_Rc;
+    Device_Handle_t Device;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    // Download EIP-207c Input Classification Engine (ICE) firmware,
+    // use the same images for all the instances of the engine
+    EIP207_Rc = EIP207_ICE_Firmware_Load(Device,
+                                         TimerPrescaler,
+                                         IPUE_Firmware_p,
+                                         IFPP_Firmware_p);
+    if (EIP207_Rc != EIP207_GLOBAL_NO_ERROR)
+        return EIP207_Rc;
+
+    // Download EIP-207c Output Classification Engine (OCE) firmware,
+    // use the same images for all the instances of the engine
+    // Download Input Classification Engine (OCE) firmware
+    EIP207_Rc = EIP207_OCE_Firmware_Load(Device,
+                                             TimerPrescaler,
+                                             OPUE_Firmware_p,
+                                             OFPP_Firmware_p);
+        // OCE is not supported by this EIP-207 HW version
+    if (EIP207_Rc != EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR &&
+        EIP207_Rc != EIP207_GLOBAL_NO_ERROR) // OCE is supported
+        return EIP207_Rc; // OCE FW download error, abort!
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+        {
+            EIP207_Global_Error_t rv;
+            uint32_t State = TrueIOArea_p->State;
+
+            // Transit to a new state
+            rv = EIP207Lib_Global_State_Set(
+                    (EIP207_Global_State_t* const)&State,
+                    EIP207_GLOBAL_STATE_FW_LOADED);
+
+            TrueIOArea_p->State = State;
+
+            if (rv != EIP207_GLOBAL_NO_ERROR)
+                return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+        }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_HWRevision_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_HWRevision_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        EIP207_Global_Capabilities_t * const Capabilities_p)
+{
+    Device_Handle_t Device;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP207_GLOBAL_CHECK_POINTER(Capabilities_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP207Lib_HWRevision_Get(Device,
+                             &Capabilities_p->EIP207_Options,
+                             &Capabilities_p->EIP207_Version);
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_GlobalStats_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_GlobalStats_t * const GlobalStats_p)
+{
+    Device_Handle_t Device;
+    EIP207_Global_Error_t rv;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP207_GLOBAL_CHECK_POINTER(GlobalStats_p);
+
+    if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    rv = EIP207_ICE_GlobalStats_Get(Device, CE_Number, &GlobalStats_p->ICE);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    rv = EIP207_OCE_GlobalStats_Get(Device, CE_Number, &GlobalStats_p->OCE);
+    if (rv == EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+        return EIP207_GLOBAL_NO_ERROR; // OCE is not supported
+    else                               // by this EIP-207 HW version
+        return rv;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_ClockCount_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_Clock_t * const Clock_p)
+{
+    Device_Handle_t Device;
+    EIP207_Global_Error_t rv;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP207_GLOBAL_CHECK_POINTER(Clock_p);
+
+    if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    rv = EIP207_ICE_ClockCount_Get(Device, CE_Number, &Clock_p->ICE);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    rv = EIP207_OCE_ClockCount_Get(Device, CE_Number, &Clock_p->OCE);
+    if (rv == EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+        return EIP207_GLOBAL_NO_ERROR; // OCE is not supported
+    else                               // by this EIP-207 HW version
+        return rv;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_Global_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_Status_Get(
+        EIP207_Global_IOArea_t * const IOArea_p,
+        const unsigned int CE_Number,
+        EIP207_Global_Status_t * const Status_p,
+        bool * const fFatalError_p)
+{
+    unsigned int i;
+    Device_Handle_t Device;
+    EIP207_Global_Error_t rv;
+    bool fFatalError = false;
+    volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP207_GLOBAL_CHECK_POINTER(Status_p);
+    EIP207_GLOBAL_CHECK_POINTER(fFatalError_p);
+
+    if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+        return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    rv = EIP207_ICE_Status_Get(Device, CE_Number, &Status_p->ICE);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    rv = EIP207_OCE_Status_Get(Device, CE_Number, &Status_p->OCE);
+    if (rv != EIP207_GLOBAL_NO_ERROR &&
+        rv != EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+        return rv;
+
+    EIP207_FLUE_Status_Get(Device, &Status_p->FLUE);
+
+    if (Status_p->ICE.fPUE_EccDerr   ||
+        Status_p->ICE.fFPP_EccDerr   ||
+        Status_p->OCE.fPUE_EccDerr ||
+        Status_p->OCE.fFPP_EccDerr ||
+        Status_p->ICE.fTimerOverflow ||
+        Status_p->OCE.fTimerOverflow ||
+        Status_p->FLUE.Error1 != 0   ||
+        Status_p->FLUE.Error2 != 0)
+        fFatalError = true;
+
+    for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+    {
+        EIP207_RC_Internal_Status_Get(Device,
+                                      i,
+                                      &Status_p->FRC[i],
+                                      &Status_p->TRC[i],
+                                      &Status_p->ARC4RC[i]);
+        if (Status_p->FRC[i].fDMAReadError ||
+            Status_p->FRC[i].fDMAWriteError ||
+            Status_p->FRC[i].fAdminEccErr ||
+            Status_p->FRC[i].fDataEccOflo ||
+            Status_p->TRC[i].fDMAReadError ||
+            Status_p->TRC[i].fDMAWriteError ||
+            Status_p->TRC[i].fAdminEccErr ||
+            Status_p->TRC[i].fDataEccOflo ||
+            Status_p->ARC4RC[i].fDMAReadError ||
+            Status_p->ARC4RC[i].fDMAWriteError ||
+            Status_p->ARC4RC[i].fAdminEccErr ||
+            Status_p->ARC4RC[i].fDataEccOflo)
+            fFatalError = true;
+
+        EIP207_RC_Internal_DebugStatistics_Get(Device,
+                                               i,
+                                               &Status_p->FRCStats[i],
+                                               &Status_p->TRCStats[i]);
+    }
+
+    *fFatalError_p = fFatalError;
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+    if (fFatalError)
+    {
+        uint32_t State = TrueIOArea_p->State;
+
+        // Transit to a new state
+        rv = EIP207Lib_Global_State_Set(
+                (EIP207_Global_State_t* const)&State,
+                EIP207_GLOBAL_STATE_FATAL_ERROR);
+
+        TrueIOArea_p->State = State;
+
+        if (rv != EIP207_GLOBAL_NO_ERROR)
+            return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c
new file mode 100644
index 0000000..9f2e019
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c
@@ -0,0 +1,572 @@
+/* eip207_ice.c
+ *
+ * EIP-207c Input Classification Engine (ICE) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207c Input Classification Engine (ICE) interface
+#include "eip207_ice.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+#include "device_rw.h"                  // Read32, Write32
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // Classification API: General
+
+// EIP-207 Firmware Download API
+#include "firmware_eip207_api_dwld.h"   // Classification API: FW download
+
+// EIP-207 Support API
+#include "eip207_support.h"
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+#include "clib.h"                       // memcmp
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Allow legacy firmware to be used, which does not have these constants.
+#ifndef FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_LAST_BYTE_COUNT
+#endif
+#ifndef FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#endif
+
+// Number fo words to check when reading firmware back.
+#define EIP207_FW_CHECK_WORD_COUNT 16
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Firmware_Load(
+        const Device_Handle_t Device,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const PUE_Firmware_p,
+        EIP207_Firmware_t * const FPP_Firmware_p)
+{
+    unsigned int NofCEs;
+    EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+    // Check if the Adapter provides the IPUE firmware image with correct size.
+    if (!PUE_Firmware_p->Image_p ||
+        PUE_Firmware_p->ImageWordCount > EIP207_IPUE_PROG_RAM_WORD_COUNT)
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+    // Check if the Adapter provides the IFPP firmware image with correct size.
+    if (!FPP_Firmware_p->Image_p ||
+        FPP_Firmware_p->ImageWordCount > EIP207_IPUE_PROG_RAM_WORD_COUNT)
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+
+    // Clear EIP-207c ICE Scratchpad RAM where the the firmware
+    // administration data will be located
+    {
+        unsigned int i, CECount, BlockCount, RequiredRAMByteCount;
+
+        RequiredRAMByteCount =
+                MAX(FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT,
+                    FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT);
+
+        // Check if the administration RAM required by the EIP-207 firmware
+        // fits into physically available scratchpad RAM
+        if ((EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT * 128) <
+            RequiredRAMByteCount)
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+        // Calculate how many 128-byte blocks are required for the firmware
+        // administration data
+        BlockCount = (RequiredRAMByteCount + 127) / 128;
+
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            // Make ICE Scratchpad RAM accessible and set the timer
+            EIP207_ICE_SCRATCH_CTRL_WR(
+                    Device,
+                    CECount,
+                    true, // Change timer
+                    true, // Enable timer
+                    (uint16_t)TimerPrescaler,
+                    EIP207_ICE_SCRATCH_TIMER_OFLO_BIT, // Timer overflow bit
+                    true, // Change access
+                    (uint8_t)BlockCount);
+
+#ifdef DEBUG
+            // Check if the timer runs
+            {
+                uint32_t Value32;
+                unsigned int i;
+
+                for (i = 0; i < 10; i++)
+                {
+                    Value32 = Device_Read32(Device,
+                                            EIP207_ICE_REG_TIMER_LO(CECount));
+
+                    if (Value32 == 0)
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+            }
+#endif
+
+            // Write the ICE Scratchpad RAM with 0
+            for(i = 0; i < (BlockCount * 32); i++)
+            {
+                Device_Write32(Device,
+                               EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                                                           i * sizeof(uint32_t),
+                               0);
+#ifdef DEBUG
+                // Perform read-back check
+                {
+                    uint32_t Value32 =
+                        Device_Read32(
+                               Device,
+                               EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                                                           i * sizeof(uint32_t));
+
+                    if (Value32 != 0)
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+#endif
+            }
+        }
+
+        // Leave the scratchpad RAM accessible for the Host
+    }
+
+    // Download the firmware
+    {
+        unsigned int CECount;
+#ifdef DEBUG
+        unsigned int i;
+#endif
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            // Reset the Input Flow Post-Processor micro-engine (IFPP) to make its
+            // Program RAM accessible
+            EIP207_ICE_FPP_CTRL_WR(Device,
+                                   CECount,
+                                   0,     // No start address for debug mode
+                                   1,       // Clear ECC correctable error
+                                   1,       // Clear ECC non-correctable error
+                                   false, // Debug mode OFF
+                                   true); // SW Reset ON
+
+            // Enable access to IFPP Program RAM
+            EIP207_ICE_RAM_CTRL_WR(Device, CECount, false, true);
+        }
+
+#ifdef DEBUG
+        // Write the Input Flow post-Processor micro-Engine firmware
+        for(i = 0; i < FPP_Firmware_p->ImageWordCount; i++)
+        {
+            Device_Write32(Device,
+                           EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+                           FPP_Firmware_p->Image_p[i]);
+            // Perform read-back check
+            {
+                uint32_t Value32 =
+                    Device_Read32(
+                           Device,
+                           EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+                if (Value32 != FPP_Firmware_p->Image_p[i])
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+            }
+        }
+#else
+        Device_Write32Array(Device,
+                            EIP207_CS_RAM_XS_SPACE_BASE,
+                            FPP_Firmware_p->Image_p,
+                            FPP_Firmware_p->ImageWordCount);
+        // Perform read-back check of small subset
+        {
+            static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+            Device_Read32Array(Device,
+                               EIP207_CS_RAM_XS_SPACE_BASE,
+                               ReadBuf,
+                               EIP207_FW_CHECK_WORD_COUNT);
+            if (memcmp(ReadBuf,
+                       FPP_Firmware_p->Image_p,
+                       EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+                return EIP207_GLOBAL_INTERNAL_ERROR;
+
+        }
+#endif
+
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            // Disable access to IFPP Program RAM
+            // Enable access to IPUE Program RAM
+            EIP207_ICE_RAM_CTRL_WR(Device, CECount, true, false);
+
+            // Reset the Input Pull-Up micro-Engine (IPUE) to make its
+            // Program RAM accessible
+            EIP207_ICE_PUE_CTRL_WR(Device,
+                                   CECount,
+                                   0,     // No start address for debug mode
+                                   1,       // Clear ECC correctable error
+                                   1,       // Clear ECC non-correctable error
+                                   false, // Debug mode OFF
+                                   true); // SW Reset ON
+        }
+
+#ifdef DEBUG
+        // Write the Input Pull-Up micro-Engine firmware
+        for(i = 0; i < PUE_Firmware_p->ImageWordCount; i++)
+        {
+            Device_Write32(Device,
+                           EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+                           PUE_Firmware_p->Image_p[i]);
+            // Perform read-back check
+            {
+                uint32_t Value32 =
+                    Device_Read32(
+                           Device,
+                           EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+                if (Value32 != PUE_Firmware_p->Image_p[i])
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+            }
+        }
+#else
+        Device_Write32Array(Device,
+                            EIP207_CS_RAM_XS_SPACE_BASE,
+                            PUE_Firmware_p->Image_p,
+                            PUE_Firmware_p->ImageWordCount);
+        // Perform read-back check of small subset
+        {
+            static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+            Device_Read32Array(Device,
+                               EIP207_CS_RAM_XS_SPACE_BASE,
+                               ReadBuf,
+                               EIP207_FW_CHECK_WORD_COUNT);
+            if (memcmp(ReadBuf,
+                       PUE_Firmware_p->Image_p,
+                       EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+                return EIP207_GLOBAL_INTERNAL_ERROR;
+
+        }
+#endif
+
+        // Disable access to IPUE Program RAM
+        for (CECount = 0; CECount < NofCEs; CECount++)
+            EIP207_ICE_RAM_CTRL_WR(Device, CECount, false, false);
+
+#ifdef EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+        // Check the firmware version and start all the engines
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            uint32_t Value32;
+            unsigned int Ma, Mi, Pl, i;
+            bool fUpdated;
+
+            // Start the IFPP in Debug mode for the firmware version check
+            EIP207_ICE_FPP_CTRL_WR(
+                        Device,
+                        CECount,
+                        FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR,
+                        1,       // Clear ECC correctable error
+                        1,       // Clear ECC non-correctable error
+                        true,    // Debug mode ON
+                        false);  // SW Reset OFF
+
+            // Wait for the IFPP version update
+            for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+            {
+                Value32 = Device_Read32(
+                        Device,
+                        EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                        FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_CTRL_BYTE_OFFSET);
+
+                FIRMWARE_EIP207_DWLD_IFPP_VersionUpdated_Read(Value32,
+                                                              &fUpdated);
+
+                if (fUpdated)
+                    break;
+            }
+
+            if (!fUpdated)
+                return EIP207_GLOBAL_INTERNAL_ERROR;
+
+            Value32 = Device_Read32(
+                      Device,
+                      EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                      FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_VERSION_BYTE_OFFSET);
+
+            FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+            if (FPP_Firmware_p->Major == 0 &&
+                FPP_Firmware_p->Minor == 0 &&
+                FPP_Firmware_p->PatchLevel == 0)
+            {  // Adapter did not provide expected version, return it.
+                FPP_Firmware_p->Major = Ma;
+                FPP_Firmware_p->Minor = Mi;
+                FPP_Firmware_p->PatchLevel = Pl;
+            }
+            else
+            {
+                // Adapter provided expected version, check it.
+                if (FPP_Firmware_p->Major != Ma ||
+                    FPP_Firmware_p->Minor != Mi ||
+                    FPP_Firmware_p->PatchLevel != Pl)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+            }
+
+            // Start the IPUE in Debug mode for the firmware version check
+            EIP207_ICE_PUE_CTRL_WR(
+                        Device,
+                        CECount,
+                        FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR,
+                        1,       // Clear ECC correctable error
+                        1,       // Clear ECC non-correctable error
+                        true,    // Debug mode ON
+                        false);  // SW Reset OFF
+
+            // Wait for the IPUE version update
+            for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+            {
+                Value32 = Device_Read32(
+                        Device,
+                        EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                        FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_CTRL_BYTE_OFFSET);
+
+                FIRMWARE_EIP207_DWLD_IPUE_VersionUpdated_Read(Value32,
+                                                              &fUpdated);
+
+                if (fUpdated)
+                    break;
+            }
+
+            if (!fUpdated)
+                return EIP207_GLOBAL_INTERNAL_ERROR;
+
+            Value32 = Device_Read32(
+                     Device,
+                     EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                     FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_VERSION_BYTE_OFFSET);
+
+            FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+            if (PUE_Firmware_p->Major == 0 &&
+                PUE_Firmware_p->Minor == 0 &&
+                PUE_Firmware_p->PatchLevel == 0)
+            {  // Adapter did not provide expected version, return it.
+                PUE_Firmware_p->Major = Ma;
+                PUE_Firmware_p->Minor = Mi;
+                PUE_Firmware_p->PatchLevel = Pl;
+            }
+            else
+            {
+                // Adapter provided expected version, check it.
+                if (PUE_Firmware_p->Major != Ma ||
+                    PUE_Firmware_p->Minor != Mi ||
+                    PUE_Firmware_p->PatchLevel != Pl)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+            }
+        } // for
+#else
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            // Start the IFPP in Debug mode
+            EIP207_ICE_FPP_CTRL_WR(
+                            Device,
+                            CECount,
+                            FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR,
+                            1,       // Clear ECC correctable error
+                            1,       // Clear ECC non-correctable error
+                            true,    // Debug mode ON
+                            false);  // SW Reset OFF
+
+            // Start the IPUE in Debug mode
+            EIP207_ICE_PUE_CTRL_WR(
+                            Device,
+                            CECount,
+                            FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR,
+                            1,       // Clear ECC correctable error
+                            1,       // Clear ECC non-correctable error
+                            true,    // Debug mode ON
+                            false);  // SW Reset OFF
+        } // for
+#endif // EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+        for (CECount = 0; CECount < NofCEs; CECount++)
+        {
+            uint32_t InputBufferSize = Device_Read32(
+                Device,
+                EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+                4*33) & MASK_16_BITS;
+            if (InputBufferSize != 0)
+            {
+                if (PUE_Firmware_p->Major > 3 ||
+                    (PUE_Firmware_p->Major ==3 &&
+                     PUE_Firmware_p->Minor >=1))
+                {
+                    InputBufferSize -= 2048;
+                }
+                else
+                {
+                    InputBufferSize = (InputBufferSize * 3) / 4;
+                }
+                EIP207_ICE_ADAPT_CTRL_WR(Device, CECount, InputBufferSize);
+            }
+            EIP207_ICE_PUTF_CTRL_WR(Device, CECount, 3, false);
+            EIP207_ICE_PPTF_CTRL_WR(Device, CECount, 0, false);
+        }
+    }
+
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_GlobalStats_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_ICE_GlobalStats_t * const ICE_GlobalStats_p)
+{
+    EIP207_Global_Error_t rv;
+
+    rv = EIP207_Global_Read64(
+                       Device,
+                       EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                         FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_LO_BYTE_OFFSET,
+                       EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                         FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_HI_BYTE_OFFSET,
+                       &ICE_GlobalStats_p->DroppedPacketsCounter);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    rv = EIP207_Global_Read64(
+                     Device,
+                     EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                       FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_LO_BYTE_OFFSET,
+                     EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                       FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_HI_BYTE_OFFSET,
+                     &ICE_GlobalStats_p->InboundOctetsCounter);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    rv = EIP207_Global_Read64(
+                    Device,
+                    EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                      FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_LO_BYTE_OFFSET,
+                    EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                      FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_HI_BYTE_OFFSET,
+                    &ICE_GlobalStats_p->OutboundOctetsCounter);
+    if (rv != EIP207_GLOBAL_NO_ERROR)
+        return rv;
+
+    ICE_GlobalStats_p->InboundPacketsCounter =
+    Device_Read32(Device,
+                  EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                  FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_PKT_BYTE_OFFSET);
+
+    ICE_GlobalStats_p->OutboundPacketCounter =
+    Device_Read32(Device,
+                  EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                  FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_PKT_BYTE_OFFSET);
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_ClockCount_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_Value64_t * const ICE_Clock_p)
+{
+    return EIP207_Global_Read64(
+                            Device,
+                            EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                              FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_LO_BYTE_OFFSET,
+                            EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+                              FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_HI_BYTE_OFFSET,
+                            ICE_Clock_p);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_ICE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_CE_Status_t * const ICE_Status_p)
+{
+    EIP207_ICE_PUE_CTRL_RD_CLEAR(Device,
+                           CE_Number,
+                           &ICE_Status_p->fPUE_EccCorr,
+                           &ICE_Status_p->fPUE_EccDerr);
+
+    EIP207_ICE_FPP_CTRL_RD_CLEAR(Device,
+                           CE_Number,
+                           &ICE_Status_p->fFPP_EccCorr,
+                           &ICE_Status_p->fFPP_EccDerr);
+
+    EIP207_ICE_SCRATCH_CTRL_RD(Device,
+                               CE_Number,
+                               &ICE_Status_p->fTimerOverflow);
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_ice.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c
new file mode 100644
index 0000000..7d29ed2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c
@@ -0,0 +1,514 @@
+/* eip207_oce.c
+ *
+ * EIP-207c Output Classification Engine (OCE) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207c Output Classification Engine (OCE) interface
+#include "eip207_oce.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t, bool
+
+// Driver Framework C Run-Time Library Abstraction API
+#include "clib.h"                 // ZEROINIT
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+#include "device_rw.h"                  // Read32, Write32
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // Classification API: General
+
+// EIP-207 Firmware Download API
+#include "firmware_eip207_api_dwld.h"   // Classification API: FW download
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+// EIP97 Global init API
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Allow legacy firmware to be used, which does not have these constants.
+#ifndef FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_LAST_BYTE_COUNT
+#endif
+#ifndef FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#endif
+
+// Number fo words to check when reading firmware back.
+#define EIP207_FW_CHECK_WORD_COUNT 16
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Firmware_Load(
+        const Device_Handle_t Device,
+        const unsigned int TimerPrescaler,
+        EIP207_Firmware_t * const PUE_Firmware_p,
+        EIP207_Firmware_t * const FPP_Firmware_p)
+{
+    unsigned int NofCEs;
+
+    if ((EIP97_SupportedFuncs_Get() & BIT_1) != 0)
+    {
+        EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+        // Check if the Adapter provides the OPUE firmware image with correct size.
+        if (!PUE_Firmware_p->Image_p ||
+            PUE_Firmware_p->ImageWordCount > EIP207_OPUE_PROG_RAM_WORD_COUNT)
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+        // Check if the Adapter provides the OFPP firmware image with correct size.
+        if (!FPP_Firmware_p->Image_p ||
+            FPP_Firmware_p->ImageWordCount > EIP207_OPUE_PROG_RAM_WORD_COUNT)
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+
+        // Clear EIP-207c OCE Scratchpad RAM where the the firmware
+        // administration data will be located
+        {
+            unsigned int i, CECount, BlockCount, RequiredRAMByteCount;
+
+            RequiredRAMByteCount =
+                MAX(FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT,
+                    FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT);
+
+            // Check if the administration RAM required by the EIP-207 firmware
+            // fits into physically available scratchpad RAM
+            if ((EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT * 128) <
+                RequiredRAMByteCount)
+                return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+            // Calculate how many 128-byte blocks are required for the firmware
+            // administration data
+            BlockCount = (RequiredRAMByteCount + 127) / 128;
+
+            for (CECount = 0; CECount < NofCEs; CECount++)
+            {
+                // Make OCE Scratchpad RAM accessible and set the timer
+                EIP207_OCE_SCRATCH_CTRL_WR(
+                    Device,
+                    CECount,
+                    true, // Change timer
+                    true, // Enable timer
+                    (uint16_t)TimerPrescaler,
+                    EIP207_OCE_SCRATCH_TIMER_OFLO_BIT, // Timer overflow bit
+                    true, // Change access
+                    (uint8_t)BlockCount);
+
+#ifdef DEBUG
+                // Check if the timer runs
+                {
+                    uint32_t Value32;
+                    unsigned int i;
+
+                    for (i = 0; i < 10; i++)
+                    {
+                        Value32 = Device_Read32(Device,
+                                                EIP207_OCE_REG_TIMER_LO(CECount));
+
+                        if (Value32 == 0)
+                            return EIP207_GLOBAL_INTERNAL_ERROR;
+                    }
+                }
+#endif
+
+                // Write the OCE Scratchpad RAM with 0
+                for(i = 0; i < (BlockCount * 32); i++)
+                {
+                    Device_Write32(Device,
+                                   EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                                   i * sizeof(uint32_t),
+                                   0);
+#ifdef DEBUG
+                    // Perform read-back check
+                    {
+                        uint32_t Value32 =
+                            Device_Read32(
+                                Device,
+                                EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                                i * sizeof(uint32_t));
+
+                        if (Value32 != 0)
+                            return EIP207_GLOBAL_INTERNAL_ERROR;
+                    }
+#endif
+                }
+            }
+
+            // Leave the scratchpad RAM accessible for the Host
+        }
+
+        // Download the firmware
+        {
+            unsigned int CECount;
+#ifdef DEBUG
+            unsigned int i;
+#endif
+            for (CECount = 0; CECount < NofCEs; CECount++)
+            {
+                // Reset the Input Flow Post-Processor micro-engine (OFPP) to make its
+                // Program RAM accessible
+                EIP207_OCE_FPP_CTRL_WR(Device,
+                                       CECount,
+                                       0,     // No start address for debug mode
+                                       1,       // Clear ECC correctable error
+                                       1,       // Clear ECC non-correctable error
+                                       false, // Debug mode OFF
+                                       true); // SW Reset ON
+
+                // Enable access to OFPP Program RAM
+                EIP207_OCE_RAM_CTRL_WR(Device, CECount, false, true);
+            }
+
+#ifdef DEBUG
+            // Write the Input Flow post-Processor micro-Engine firmware
+            for(i = 0; i < FPP_Firmware_p->ImageWordCount; i++)
+            {
+                Device_Write32(Device,
+                               EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+                               FPP_Firmware_p->Image_p[i]);
+                // Perform read-back check
+                {
+                    uint32_t Value32 =
+                        Device_Read32(
+                            Device,
+                           EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+                    if (Value32 != FPP_Firmware_p->Image_p[i])
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+            }
+#else
+            Device_Write32Array(Device,
+                                EIP207_CS_RAM_XS_SPACE_BASE,
+                                FPP_Firmware_p->Image_p,
+                                FPP_Firmware_p->ImageWordCount);
+            // Perform read-back check of small subset
+            {
+                static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+                Device_Read32Array(Device,
+                                   EIP207_CS_RAM_XS_SPACE_BASE,
+                                   ReadBuf,
+                                   EIP207_FW_CHECK_WORD_COUNT);
+                if (memcmp(ReadBuf,
+                           FPP_Firmware_p->Image_p,
+                           EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+
+            }
+#endif
+
+            for (CECount = 0; CECount < NofCEs; CECount++)
+            {
+                // Disable access to OFPP Program RAM
+                // Enable access to OPUE Program RAM
+                EIP207_OCE_RAM_CTRL_WR(Device, CECount, true, false);
+
+                // Reset the Input Pull-Up micro-Engine (OPUE) to make its
+                // Program RAM accessible
+                EIP207_OCE_PUE_CTRL_WR(Device,
+                                       CECount,
+                                       0,     // No start address for debug mode
+                                       1,       // Clear ECC correctable error
+                                       1,       // Clear ECC non-correctable error
+                                   false, // Debug mode OFF
+                                       true); // SW Reset ON
+            }
+
+#ifdef DEBUG
+            // Write the Input Pull-Up micro-Engine firmware
+            for(i = 0; i < PUE_Firmware_p->ImageWordCount; i++)
+            {
+                Device_Write32(Device,
+                               EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+                               PUE_Firmware_p->Image_p[i]);
+                // Perform read-back check
+                {
+                    uint32_t Value32 =
+                        Device_Read32(
+                            Device,
+                            EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+                    if (Value32 != PUE_Firmware_p->Image_p[i])
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+            }
+#else
+            Device_Write32Array(Device,
+                                EIP207_CS_RAM_XS_SPACE_BASE,
+                                PUE_Firmware_p->Image_p,
+                                PUE_Firmware_p->ImageWordCount);
+            // Perform read-back check of small subset
+            {
+                static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+                Device_Read32Array(Device,
+                                   EIP207_CS_RAM_XS_SPACE_BASE,
+                                   ReadBuf,
+                               EIP207_FW_CHECK_WORD_COUNT);
+                if (memcmp(ReadBuf,
+                           PUE_Firmware_p->Image_p,
+                           EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+
+            }
+#endif
+
+            // Disable access to OPUE Program RAM
+            for (CECount = 0; CECount < EIP207_GLOBAL_MAX_NOF_CE_TO_USE; CECount++)
+                EIP207_OCE_RAM_CTRL_WR(Device, CECount, false, false);
+
+#ifdef EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+            // Check the firmware version and start all the engines
+            for (CECount = 0; CECount < NofCEs; CECount++)
+            {
+                uint32_t Value32;
+                unsigned int Ma, Mi, Pl, i;
+                bool fUpdated;
+
+                // Start the OFPP in Debug mode for the firmware version check
+                EIP207_OCE_FPP_CTRL_WR(
+                    Device,
+                    CECount,
+                    FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR,
+                    1,       // Clear ECC correctable error
+                    1,       // Clear ECC non-correctable error
+                    true,    // Debug mode ON
+                    false);  // SW Reset OFF
+
+                // Wait for the OFPP version update
+                for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+                {
+                    Value32 = Device_Read32(
+                        Device,
+                        EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                        FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_CTRL_BYTE_OFFSET);
+
+                    FIRMWARE_EIP207_DWLD_OFPP_VersionUpdated_Read(Value32,
+                                                                  &fUpdated);
+
+                    if (fUpdated)
+                        break;
+                }
+
+                if (!fUpdated)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+
+                Value32 = Device_Read32(
+                    Device,
+                    EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                    FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_VERSION_BYTE_OFFSET);
+
+                FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+                if (FPP_Firmware_p->Major == 0 &&
+                    FPP_Firmware_p->Minor == 0 &&
+                    FPP_Firmware_p->PatchLevel == 0)
+                {  // Adapter did not provide expected version, return it.
+                    FPP_Firmware_p->Major = Ma;
+                    FPP_Firmware_p->Minor = Mi;
+                    FPP_Firmware_p->PatchLevel = Pl;
+                }
+                else
+                {
+                    // Adapter provided expected version, check it.
+                    if (FPP_Firmware_p->Major != Ma ||
+                        FPP_Firmware_p->Minor != Mi ||
+                        FPP_Firmware_p->PatchLevel != Pl)
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+
+                // Start the OPUE in Debug mode for the firmware version check
+                EIP207_OCE_PUE_CTRL_WR(
+                    Device,
+                    CECount,
+                    FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR,
+                    1,       // Clear ECC correctable error
+                    1,       // Clear ECC non-correctable error
+                    true,    // Debug mode ON
+                    false);  // SW Reset OFF
+
+                // Wait for the OPUE version update
+                for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+                {
+                    Value32 = Device_Read32(
+                        Device,
+                        EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                        FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_CTRL_BYTE_OFFSET);
+
+                    FIRMWARE_EIP207_DWLD_OPUE_VersionUpdated_Read(Value32,
+                                                                  &fUpdated);
+
+                    if (fUpdated)
+                        break;
+                }
+
+                if (!fUpdated)
+                    return EIP207_GLOBAL_INTERNAL_ERROR;
+
+                Value32 = Device_Read32(
+                    Device,
+                     EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+                    FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_VERSION_BYTE_OFFSET);
+
+                FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+                if (PUE_Firmware_p->Major == 0 &&
+                    PUE_Firmware_p->Minor == 0 &&
+                PUE_Firmware_p->PatchLevel == 0)
+                {  // Adapter did not provide expected version, return it.
+                    PUE_Firmware_p->Major = Ma;
+                    PUE_Firmware_p->Minor = Mi;
+                    PUE_Firmware_p->PatchLevel = Pl;
+                }
+                else
+                {
+                    // Adapter provided expected version, check it.
+                    if (PUE_Firmware_p->Major != Ma ||
+                    PUE_Firmware_p->Minor != Mi ||
+                        PUE_Firmware_p->PatchLevel != Pl)
+                        return EIP207_GLOBAL_INTERNAL_ERROR;
+                }
+            } // for
+#else
+            for (CECount = 0; CECount < EIP207_GLOBAL_MAX_NOF_CE_TO_USE; CECount++)
+            {
+            // Start the OFPP in Debug mode
+                EIP207_OCE_FPP_CTRL_WR(
+                    Device,
+                    CECount,
+                    FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR,
+                    1,       // Clear ECC correctable error
+                    1,       // Clear ECC non-correctable error
+                    true,    // Debug mode ON
+                    false);  // SW Reset OFF
+
+                // Start the OPUE in Debug mode
+                EIP207_OCE_PUE_CTRL_WR(
+                    Device,
+                    CECount,
+                    FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR,
+                    1,       // Clear ECC correctable error
+                    1,       // Clear ECC non-correctable error
+                            true,    // Debug mode ON
+                    false);  // SW Reset OFF
+            } // for
+#endif // EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+        }
+    }
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_GlobalStats_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_OCE_GlobalStats_t * const OCE_GlobalStats_p)
+{
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(CE_Number);
+
+    // Not used / implemented yet
+    ZEROINIT(*OCE_GlobalStats_p);
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_ClockCount_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_Value64_t * const OCE_Clock_p)
+{
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(CE_Number);
+
+    // Not used / implemented yet
+    ZEROINIT(*OCE_Clock_p);
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_OCE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CE_Number,
+        EIP207_Global_CE_Status_t * const OCE_Status_p)
+{
+    if ((EIP97_SupportedFuncs_Get() & BIT_1) != 0)
+    {
+        EIP207_OCE_PUE_CTRL_RD_CLEAR(Device,
+                                     CE_Number,
+                                     &OCE_Status_p->fPUE_EccCorr,
+                                     &OCE_Status_p->fPUE_EccDerr);
+
+        EIP207_OCE_FPP_CTRL_RD_CLEAR(Device,
+                                     CE_Number,
+                                     &OCE_Status_p->fFPP_EccCorr,
+                                     &OCE_Status_p->fFPP_EccDerr);
+
+        EIP207_OCE_SCRATCH_CTRL_RD(Device,
+                                   CE_Number,
+                                   &OCE_Status_p->fTimerOverflow);
+    }
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_oce.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c
new file mode 100644
index 0000000..42ea46c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c
@@ -0,0 +1,107 @@
+/* eip207_rc.c
+ *
+ * EIP-207 Record Cache (RC) interface High-Performance (HP) implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Record Cache (RC) interface
+#include "eip207_rc.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_BaseAddr_Set
+ */
+void
+EIP207_RC_BaseAddr_Set(
+            const Device_Handle_t Device,
+            const uint32_t CacheBase,
+            const unsigned int CacheNr,
+            const uint32_t Address,
+            const uint32_t UpperAddress)
+{
+    // Not implemented
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(CacheBase);
+    IDENTIFIER_NOT_USED(CacheNr);
+    IDENTIFIER_NOT_USED(Address);
+    IDENTIFIER_NOT_USED(UpperAddress);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Update
+ */
+void
+EIP207_RC_Record_Update(
+        const Device_Handle_t Device,
+        const uint32_t CacheBase,
+        const unsigned int CacheNr,
+        const uint32_t Rec_DMA_Addr,
+        const uint8_t Command,
+        const unsigned int ByteOffset,
+        const uint32_t Value32)
+{
+    // Not implemented
+    IDENTIFIER_NOT_USED(Command);
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(CacheBase);
+    IDENTIFIER_NOT_USED(Device);
+    IDENTIFIER_NOT_USED(CacheNr);
+    IDENTIFIER_NOT_USED(Rec_DMA_Addr);
+    IDENTIFIER_NOT_USED(ByteOffset);
+    IDENTIFIER_NOT_USED(Value32);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Dummy_Addr_Get
+ */
+unsigned int
+EIP207_RC_Record_Dummy_Addr_Get(void)
+{
+    return EIP207_RC_RECORD_DUMMY_ADDRESS;
+}
+
+
+/* end of file eip207_rc.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c
new file mode 100644
index 0000000..4ca5d25
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c
@@ -0,0 +1,808 @@
+/* eip207_rc_internal.c
+ *
+ * EIP-207 Record Cache (RC) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// EIP-207 Record Cache (RC) internal interface
+#include "eip207_rc_internal.h"
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h"              // EIP-207 Level 0 macros
+
+// EIP-206 Global Control Driver Library Internal interfaces
+#include "eip206_level0.h"              // EIP-206 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h"     // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#if FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT <= \
+                FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT
+#define EIP207_RC_ARC4_SIZE                             0
+#elif FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT <= \
+                FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT_LARGE
+#define EIP207_RC_ARC4_SIZE                             1
+#else
+#error "Error: ARC4 State Record size too big"
+#endif
+
+// Minimum number of entries in the Record Cache
+#define EIP207_RC_MIN_ENTRY_COUNT                       32
+
+// Maximum number of entries in the Record Cache
+#define EIP207_RC_MAX_ENTRY_COUNT                       4096
+
+// Maximum number of records in cachs
+#define EIP207_RC_MAX_RECORD_COUNT                      1023
+
+// Number of header words (32-bits) in a cache record
+#define EIP207_RC_HEADER_WORD_COUNT                     4
+
+// Number of 32-bit words in one administration memory word
+#define EIP207_RC_ADMIN_MEMWORD_WORD_COUNT              4
+
+// Number of hash table entries in one administration memory word
+#define EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT             8
+
+// Null value used in Record Caches
+#define EIP207_RC_NULL_VALUE                            0x3FF
+
+// Checks for the required configuration parameters
+#ifndef EIP207_FRC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_FRC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_FRC_ADMIN_RAM_WORD_COUNT
+
+#ifndef EIP207_TRC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_TRC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_TRC_ADMIN_RAM_WORD_COUNT
+
+#ifndef EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT
+
+// Minimum required Record Cache Admin RAM size
+#define EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT \
+      (((EIP207_RC_MIN_ENTRY_COUNT / EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT) * \
+          EIP207_RC_ADMIN_MEMWORD_WORD_COUNT) + \
+             EIP207_RC_HEADER_WORD_COUNT * EIP207_RC_MIN_ENTRY_COUNT)
+
+// Check if the configured FRC Admin RAM size is large enough to contain
+// the minimum required number of record headers with their hash table
+#if EIP207_FRC_ADMIN_RAM_WORD_COUNT > 0 && \
+    EIP207_FRC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured FRC Admin RAM size is too small"
+#endif
+
+// Check if the configured TRC Admin RAM size is large enough to contain
+// the minimum required number of record headers with their hash table
+#if EIP207_TRC_ADMIN_RAM_WORD_COUNT > 0 && \
+    EIP207_TRC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured TRC Admin RAM size is too small"
+#endif
+
+// Check if the (optional) configured ARC4RC Admin RAM size is large enough
+// to contain the minimum required number of record headers
+// with their hash table
+#if EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT > 0 && \
+    EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured ARC4RC Admin RAM size is too small"
+#endif
+
+// Hash Table Size calculation for *RC_p_PARAMS registers
+// Hash Table entry count =
+//      2 ^ (Hash Table Size + EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR)
+#define EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR      5
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_RC_Internal_LowerPowerOfTwo
+ *
+ * Rounds down a value to the lower or equal power of two value.
+ */
+static unsigned int
+EIP207Lib_RC_Internal_LowerPowerOfTwo(const unsigned int Value,
+                                      unsigned int * const Power)
+{
+    unsigned int v = Value;
+    unsigned int i = 0;
+
+    if (v == 0)
+        return v;
+
+    while (v)
+    {
+        v = v >> 1;
+        i++;
+    }
+
+    v = 1 << (i - 1);
+
+    *Power = i - 1;
+
+    return v;
+}
+
+
+#define EIP207_RC_DATA_WORDCOUNT_MAX 131072
+#define EIP207_RC_DATA_WORDCOUNT_MIN 256
+#define EIP207_RC_ADMIN_WORDCOUNT_MAX 16384
+#define EIP207_RC_ADMIN_WORDCOUNT_MIN 64
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Bank_Set
+ *
+ * Set the bank for the CS RAM to the given address.
+ *
+ * Device (input)
+ *     Device to use.
+ *
+ * BankNr (input)
+ *     Bank number from 0 to 7.
+ *
+ */
+static void
+EIP207Lib_Bank_Set(
+    const Device_Handle_t Device,
+    uint32_t BankNr)
+{
+    uint32_t OldValue = Device_Read32(Device, EIP207_CS_REG_RAM_CTRL);
+
+    uint32_t NewValue = (OldValue & 0xffff8fff) | ((BankNr&0x7) << 12);
+
+    Device_Write32(Device, EIP207_CS_REG_RAM_CTRL, NewValue);
+}
+
+
+static void
+EIP207Lib_RAM_Write32(
+        const Device_Handle_t Device,
+        uint32_t Address,
+        uint32_t Value)
+{
+    Device_Write32(Device,
+                   EIP207_CS_RAM_XS_SPACE_BASE + Address,
+                   Value);
+}
+
+static uint32_t
+EIP207Lib_RAM_Read32(
+        const Device_Handle_t Device,
+        uint32_t Address)
+{
+    return Device_Read32(Device,
+                         EIP207_CS_RAM_XS_SPACE_BASE + Address);
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_RAMSize_Probe
+ *
+ * Probe the size of the accessible RAM, do not access more memory than
+ * indicated by MaxSize.
+ *
+ * Device (input)
+ *     Device to use.
+ *
+ * MaxSize (input)
+ *     Maximum size of RAM
+ */
+static unsigned int
+EIP207Lib_RAMSize_Probe(
+    const Device_Handle_t Device,
+    const unsigned int MaxSize)
+{
+    unsigned int MaxBank, MaxPage, MaxOffs, i, RAMSize;
+
+    if (MaxSize <= 16384)
+    {
+        // All RAM is in a single bank.
+        MaxBank = 0;
+    }
+    else
+    {
+        // Probe the maximum bank number that has (distinct) RAM.
+        for (i=0; i<8; i++)
+        {
+            EIP207Lib_Bank_Set(Device, 7 - i);
+            EIP207Lib_RAM_Write32(Device, 0, 7 - i);
+            EIP207Lib_RAM_Write32(Device, 4, 0);
+            EIP207Lib_RAM_Write32(Device, 8, 0);
+            EIP207Lib_RAM_Write32(Device, 12, 0);
+        }
+        MaxBank=0;
+        for (i=0; i<7; i++)
+        {
+            EIP207Lib_Bank_Set(Device, i);
+            if (EIP207Lib_RAM_Read32(Device, 0) != i)
+            {
+                break;
+            }
+            MaxBank = i;
+        }
+    }
+
+    EIP207Lib_Bank_Set(Device, MaxBank);
+
+    for (i=0; i<0x10000; i+=0x100)
+    {
+        EIP207Lib_RAM_Write32(Device, 0xff00-i, 0xff00-i);
+        EIP207Lib_RAM_Write32(Device, 0xff00-i+4, 0);
+        EIP207Lib_RAM_Write32(Device, 0xff00-i+8, 0);
+        EIP207Lib_RAM_Write32(Device, 0xff00-i+12, 0);
+    }
+
+    MaxPage = 0;
+    for (i=0; i<0x10000; i+=0x100)
+    {
+        if (EIP207Lib_RAM_Read32(Device, i) != i)
+        {
+            break;
+        }
+        MaxPage = i;
+    }
+
+    for (i=0; i<0x100; i+= 4)
+    {
+        EIP207Lib_RAM_Write32(Device, MaxPage + 0xfc - i, MaxPage + 0xfc - i);
+    }
+
+    MaxOffs = 0;
+
+    for (i=0; i<0x100; i+=4)
+    {
+        if (EIP207Lib_RAM_Read32(Device, MaxPage + i) != MaxPage + i)
+        {
+            break;
+        }
+        MaxOffs = i;
+    }
+
+    EIP207Lib_Bank_Set(Device, 0);
+    RAMSize = ((MaxBank<<16) + MaxPage + MaxOffs + 4) >> 2;
+
+    if (RAMSize > MaxSize)
+        RAMSize = MaxSize;
+
+    return RAMSize;
+}
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Init
+ */
+EIP207_Global_Error_t
+EIP207_RC_Internal_Init(
+        const Device_Handle_t Device,
+        const EIP207_RC_Internal_Combination_Type_t CombinationType,
+        const uint32_t CacheBase,
+        EIP207_Global_CacheParams_t * RC_Params_p,
+        const unsigned int RecordWordCount)
+{
+    unsigned int i;
+    uint16_t RC_Record2_WordCount = 0;
+    uint8_t ClocksPerTick;
+    bool fFrc = false, fTrc = false, fArc4 = false;
+    EIP207_Global_CacheParams_t * RC_p = RC_Params_p;
+    unsigned int NullVal = EIP207_RC_NULL_VALUE;
+
+    switch (CacheBase)
+    {
+        case EIP207_FRC_REG_BASE:
+            fFrc = true;
+            RC_Record2_WordCount = 0;
+            break;
+
+        case EIP207_TRC_REG_BASE:
+            fTrc = true;
+            RC_Record2_WordCount =
+                    FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT_LARGE;
+            break;
+
+        case EIP207_ARC4RC_REG_BASE:
+            fArc4 = true;
+            RC_Record2_WordCount =
+                    FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT_LARGE;
+            break;
+
+        default:
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+    }
+
+    if (CombinationType != EIP207_RC_INTERNAL_NOT_COMBINED)
+    {
+        if( fFrc ) // FRC cannot be combined
+            return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+        // Initialize all the configured for use Record Cache sets
+        for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+            EIP207_RC_PARAMS_WR(Device,
+                                CacheBase,
+                                i,     // Cache Set number
+                                false, // Disable cache RAM access
+                                false, // Block Next Command is reserved
+                                false, // Enable access cache administration RAM
+                                0,
+                                0,     // Block Time Base is reserved
+                                false, // Not used for this HW
+                                RC_Record2_WordCount); // Large record size
+
+        return EIP207_GLOBAL_NO_ERROR;
+    }
+    // Indicate if ARC4 state records are considered 'large' transform records.
+    // Only relevent inin case the TRC is used to store ARC4 state records, but
+    // without a combined cache.
+    if (fTrc)
+    {
+        unsigned int NofCEs;
+        EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+        for (i = 0; i < NofCEs; i++)
+            EIP206_ARC4_SIZE_WR(Device, i, EIP207_RC_ARC4_SIZE);
+    }
+
+    // Initialize all the configured for use Record Cache sets
+    for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+    {
+        unsigned int RC_RAM_WordCount = RC_p->DataWordCount;
+        uint8_t RC_HashTableSize;
+        unsigned int j, Power,
+                     RC_RecordCount,
+                     RC_Record_WordCount,
+                     RC_HashTable_EntryCount,
+                     RC_HashTable_WordCount,
+                     RC_AdminRAM_WordCount,
+                     RC_AdminRAM_EntryCount,
+                     RC_HashTable_ByteOffset;
+
+        if (RC_p->fEnable == false)
+            continue; // Cache is not enabled
+
+        // Enable Record Cache RAM access
+        EIP207_CS_RAM_CTRL_WR(
+            Device,
+            fFrc && i==0,
+            fFrc && i==1,
+            fFrc && i==2,
+            fTrc && i==0,
+            fTrc && i==1,
+            fTrc && i==2,
+            fArc4 && i==0,
+            fArc4 && i==1,
+            fArc4 && i==2,
+            false);               // No FLUEC cache RAM access
+
+        // Take Record Cache into reset
+        // Make cache data RAM accessible
+        EIP207_RC_PARAMS_WR(Device,
+                            CacheBase,
+                            i,     // Cache Set number
+                            true,  // Enable cache RAM access
+                            false,
+                            true, // Enable access cache data RAM
+                            0,
+                            0,
+                            false, // Not used here for this HW
+                            0);
+
+        if (RC_RAM_WordCount == 0 ||
+            RC_RAM_WordCount > EIP207_RC_DATA_WORDCOUNT_MAX)
+            RC_RAM_WordCount = EIP207_RC_DATA_WORDCOUNT_MAX;
+        // Check the size of the data RAM.
+        RC_RAM_WordCount = EIP207Lib_RAMSize_Probe(
+            Device,
+            RC_RAM_WordCount);
+
+        // Data RAM may be inaccessible on some hardware configurations,
+        // so RAM size probing may not work. Assume that provided word count
+        // input actually reflects RAM size.
+        if (RC_RAM_WordCount < EIP207_RC_DATA_WORDCOUNT_MIN)
+            RC_RAM_WordCount = MIN(RC_p->DataWordCount, EIP207_RC_DATA_WORDCOUNT_MAX);
+        if (RC_RAM_WordCount < EIP207_RC_DATA_WORDCOUNT_MIN)
+            return EIP207_GLOBAL_INTERNAL_ERROR;
+
+        RC_p->DataWordCount = RC_RAM_WordCount;
+
+        // Take Record Cache into reset
+        // Make cache administration RAM accessible
+        EIP207_RC_PARAMS_WR(Device,
+                            CacheBase,
+                            i,     // Cache Set number
+                            true,  // Enable cache RAM access
+                            false,
+                            false, // Enable access cache administration RAM
+                            0,
+                            0,
+                            false, // Not used here for this HW
+                            0);
+
+        // Get the configured RC Admin RAM size
+        RC_AdminRAM_WordCount = RC_p->AdminWordCount;
+        if (RC_AdminRAM_WordCount == 0 ||
+            RC_AdminRAM_WordCount > EIP207_RC_ADMIN_WORDCOUNT_MAX)
+            RC_AdminRAM_WordCount = EIP207_RC_ADMIN_WORDCOUNT_MAX;
+
+        RC_AdminRAM_WordCount = EIP207Lib_RAMSize_Probe(
+            Device,
+            RC_AdminRAM_WordCount);
+
+        RC_p->AdminWordCount = RC_AdminRAM_WordCount;
+
+        if (RC_AdminRAM_WordCount < EIP207_RC_ADMIN_WORDCOUNT_MIN)
+            return EIP207_GLOBAL_INTERNAL_ERROR;
+
+       // Check the size of the Admin RAM
+
+        // Determine the RC record size to use
+        if (RC_Record2_WordCount > RecordWordCount)
+            RC_Record_WordCount = RC_Record2_WordCount;
+        else
+            RC_Record_WordCount = RecordWordCount;
+
+        // Calculate the maximum possible record count that
+        // the Record Cache Data RAM can contain
+        RC_RecordCount = RC_RAM_WordCount / RC_Record_WordCount;
+        if (RC_RecordCount > EIP207_RC_MAX_RECORD_COUNT)
+            RC_RecordCount = EIP207_RC_MAX_RECORD_COUNT;
+
+        // RC_RecordCount is calculated using the configured RC Data RAM size.
+
+        // RC_AdminRAM_EntryCount is calculated using
+        // the configured RC Admin RAM size.
+
+        // Calculate the maximum possible record count that
+        // the RC Hash Table (in Record Cache Administration RAM) can contain
+        RC_AdminRAM_EntryCount = EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+                                    RC_AdminRAM_WordCount /
+                                (EIP207_RC_ADMIN_MEMWORD_WORD_COUNT +
+                                        EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+                                           EIP207_RC_HEADER_WORD_COUNT);
+
+        // Try to extend the Hash Table in the RC Admin RAM
+        if (RC_RecordCount < RC_AdminRAM_EntryCount)
+        {
+            unsigned int HTSpace_WordCount;
+
+            // Calculate the size of space available for the Hash Table
+            HTSpace_WordCount = RC_AdminRAM_WordCount -
+                                  RC_RecordCount * EIP207_RC_HEADER_WORD_COUNT;
+
+            // Calculate maximum possible Hash Table entry count
+            RC_HashTable_EntryCount = (HTSpace_WordCount /
+                                        EIP207_RC_ADMIN_MEMWORD_WORD_COUNT) *
+                                           EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT;
+        }
+        else // Extension impossible
+            RC_HashTable_EntryCount = RC_AdminRAM_EntryCount;
+
+        // Check minimum number of entries in the record cache
+        RC_HashTable_EntryCount = MAX(EIP207_RC_MIN_ENTRY_COUNT,
+                                      RC_HashTable_EntryCount);
+
+        // Check maximum number of entries in the record cache
+        RC_HashTable_EntryCount = MIN(EIP207_RC_MAX_ENTRY_COUNT,
+                                      RC_HashTable_EntryCount);
+
+        // Round down to power of two
+        Power = 0;
+        RC_HashTable_EntryCount =
+             EIP207Lib_RC_Internal_LowerPowerOfTwo(RC_HashTable_EntryCount,
+                                                   &Power);
+
+        // Hash Table Mask that determines the hash table size
+        if (Power >= EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR)
+            RC_HashTableSize =
+                    (uint8_t)(Power - EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR);
+        else
+            // Insufficient memory for Hash Table in the RC Admin RAM
+            return EIP207_GLOBAL_INTERNAL_ERROR;
+
+        // Calculate the Hash Table size in 32-bit words
+        RC_HashTable_WordCount = RC_HashTable_EntryCount /
+                                  EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+                                       EIP207_RC_ADMIN_MEMWORD_WORD_COUNT;
+
+        // Recalculate the record count that fits the RC Admin RAM space
+        // without the Hash Table, restricting for the maximum records
+        // which fit the RC Data RAM
+        {
+            // Adjusted record count which fits the RC Admin RAM
+            unsigned int RC_AdminRAM_AdjustedEntryCount =
+                             (RC_AdminRAM_WordCount -
+                                RC_HashTable_WordCount) /
+                                   EIP207_RC_HEADER_WORD_COUNT;
+
+            // Maximum record count which fits the RC Data RAM - RC_RecordCount
+            // use the minimum of the two
+            RC_RecordCount = MIN(RC_RecordCount,
+                                 RC_AdminRAM_AdjustedEntryCount);
+        }
+
+        // Clear all ECC errors
+        EIP207_RC_ECCCTRL_WR(Device, CacheBase, i, false, false, false);
+
+        // Clear all record administration words
+        // in Record Cache administration RAM
+        for (j = 0; j < RC_RecordCount; j++)
+        {
+            // Calculate byte offset for the current record
+            unsigned int ByteOffset = EIP207_CS_RAM_XS_SPACE_BASE +
+                                      j *
+                                        EIP207_RC_HEADER_WORD_COUNT *
+                                          sizeof(uint32_t);
+
+            // Write word 0
+            Device_Write32(Device,
+                           ByteOffset,
+                           (NullVal << 20) | // Hash_Collision_Prev
+                           (NullVal << 10)); // Hash_Collision_Next
+
+            // Write word 1
+            ByteOffset += sizeof(uint32_t);
+
+            if (j == RC_RecordCount - 1)
+            {
+                // Last record
+                Device_Write32(Device,
+                               ByteOffset,
+                               ((j - 1) << 10) |   // Free_List_Prev
+                               NullVal);           // Free_List_Next
+            }
+            else if (j == 0)
+            {
+                // First record
+                Device_Write32(Device,
+                               ByteOffset,
+                               (NullVal << 10) | // Free_List_Prev
+                               (j + 1));         // Free_List_Next
+            }
+            else
+            {
+                // All other records
+                Device_Write32(Device,
+                               ByteOffset,
+                               ((j - 1) << 10) | // Free_List_Prev
+                               (j + 1));         // Free_List_Next
+            }
+
+            // Write word 2
+            ByteOffset += sizeof(uint32_t);
+
+            Device_Write32(Device,
+                           ByteOffset,
+                           0); // Address_Key, low bits
+
+            // Write word 3
+            ByteOffset += sizeof(uint32_t);
+
+            Device_Write32(Device,
+                           ByteOffset,
+                           0); // Address_Key, high bits
+        } // for (records)
+
+        // Calculate byte offset for the Hash Table
+        RC_HashTable_ByteOffset = EIP207_CS_RAM_XS_SPACE_BASE +
+                            RC_RecordCount *
+                                EIP207_RC_HEADER_WORD_COUNT *
+                                    sizeof(uint32_t);
+
+        // Clear all hash table words
+        for (j = 0; j < RC_HashTable_WordCount; j++)
+            Device_Write32(Device,
+                           RC_HashTable_ByteOffset + j * sizeof(uint32_t),
+                           0x3FFFFFFF);
+
+        // Disable Record Cache RAM access
+        EIP207_CS_RAM_CTRL_DEFAULT_WR(Device);
+
+        // Write head and tail pointers to the RC Free Chain
+        EIP207_RC_FREECHAIN_WR(
+                  Device,
+                  CacheBase,
+                  i,                               // Cache Set number
+                  0,                               // head pointer
+                  (uint16_t)(RC_RecordCount - 1)); // tail pointer
+
+        // Set Hash Table start
+        // This is an offset from EIP207_CS_RAM_XS_SPACE_BASE
+        // in record administration memory words
+        EIP207_RC_PARAMS2_WR(Device,
+                             CacheBase,
+                             i,
+                             (uint16_t)RC_RecordCount,
+    /* Small Record size */  fArc4 ? 0 : (uint16_t)RecordWordCount,
+                             FIRMWARE_EIP207_RC_DMA_WR_COMB_DLY);
+
+        // Select the highest clock count as specified by
+        // the Host and the Firmware for the FRC
+#ifdef FIRMWARE_EIP207_CS_BLOCK_NEXT_COMMAND_LOGIC_DISABLE
+        ClocksPerTick = RC_p->BlockClockCount;
+#else
+        {
+            uint8_t tmp;
+
+            tmp = (uint8_t)FIRMWARE_EIP207_CS_FRC_BLOCK_TIMEBASE;
+            ClocksPerTick = RC_p->BlockClockCount >= tmp ?
+                                       CacheConf_p->FRC.BlockClockCount : tmp;
+        }
+#endif
+
+        // Take Record Cache out of reset
+        EIP207_RC_PARAMS_WR(Device,
+                            CacheBase,
+                            i,     // Cache Set number
+                            false, // Disable cache RAM access
+                            RC_p->fNonBlock,
+                            false, // Disable access cache administration RAM
+                            RC_HashTableSize,
+                            ClocksPerTick,
+                            false, // Not used here for this HW
+                            RC_Record2_WordCount); // Large record size
+
+        RC_p++;
+    } // for, i cache sets
+
+    return EIP207_GLOBAL_NO_ERROR;
+}
+
+static void
+EIP207_RC_Internal_DebugStatistics_Single_Get(
+        const Device_Handle_t Device,
+        const unsigned int CacheSetId,
+        uint32_t RegBase,
+        EIP207_Global_CacheDebugStatistics_t * const Stats_p)
+{
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFEXEC(RegBase, CacheSetId),
+                         &Stats_p->PrefetchExec);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFBLCK(RegBase, CacheSetId),
+                         &Stats_p->PrefetchBlock);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFDMA(RegBase, CacheSetId),
+                         &Stats_p->PrefetchDMA);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_SELOPS(RegBase, CacheSetId),
+                         &Stats_p->SelectOps);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_SELDMA(RegBase, CacheSetId),
+                         &Stats_p->SelectDMA);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_IDMAWR(RegBase, CacheSetId),
+                         &Stats_p->IntDMAWrite);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_XDMAWR(RegBase, CacheSetId),
+                         &Stats_p->ExtDMAWrite);
+    EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_INVCMD(RegBase, CacheSetId),
+                         &Stats_p->InvalidateOps);
+    EIP207_RC_RDMAERRFLGS_RD(Device, RegBase, CacheSetId,
+                             &Stats_p->ReadDMAErrFlags);
+    EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_RDMAERR(RegBase, CacheSetId),
+                          &Stats_p->ReadDMAErrors);
+    EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_WDMAERR(RegBase, CacheSetId),
+                          &Stats_p->WriteDMAErrors);
+    EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_INVECC(RegBase, CacheSetId),
+                          &Stats_p->InvalidateECC);
+    EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_DATECC_CORR(RegBase, CacheSetId),
+                          &Stats_p->DataECCCorr);
+    EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_ADMECC_CORR(RegBase, CacheSetId),
+                          &Stats_p->AdminECCCorr);
+
+}
+
+
+void
+EIP207_RC_Internal_DebugStatistics_Get(
+        const Device_Handle_t Device,
+        const unsigned int CacheSetId,
+        EIP207_Global_CacheDebugStatistics_t * const FRC_Stats_p,
+        EIP207_Global_CacheDebugStatistics_t * const TRC_Stats_p)
+{
+    EIP207_RC_Internal_DebugStatistics_Single_Get(
+        Device,
+        CacheSetId,
+        EIP207_FRC_REG_BASE,
+        FRC_Stats_p);
+    EIP207_RC_Internal_DebugStatistics_Single_Get(
+        Device,
+        CacheSetId,
+        EIP207_TRC_REG_BASE,
+        TRC_Stats_p);
+}
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Status_Get
+ */
+void
+EIP207_RC_Internal_Status_Get(
+        const Device_Handle_t Device,
+        const unsigned int CacheSetId,
+        EIP207_Global_CacheStatus_t * const FRC_Status_p,
+        EIP207_Global_CacheStatus_t * const TRC_Status_p,
+        EIP207_Global_CacheStatus_t * const ARC4RC_Status_p)
+{
+    // Read FRC status
+    EIP207_RC_PARAMS_RD(Device,
+                        EIP207_FRC_REG_BASE,
+                        CacheSetId,
+                        &FRC_Status_p->fDMAReadError,
+                        &FRC_Status_p->fDMAWriteError);
+
+    EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+                               EIP207_FRC_REG_BASE,
+                               CacheSetId,
+                               &FRC_Status_p->fDataEccOflo,
+                               &FRC_Status_p->fDataEccErr,
+                               &FRC_Status_p->fAdminEccErr);
+
+    // Read TRC status
+    EIP207_RC_PARAMS_RD(Device,
+                        EIP207_TRC_REG_BASE,
+                        CacheSetId,
+                        &TRC_Status_p->fDMAReadError,
+                        &TRC_Status_p->fDMAWriteError);
+
+    EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+                               EIP207_TRC_REG_BASE,
+                               CacheSetId,
+                               &TRC_Status_p->fDataEccOflo,
+                               &TRC_Status_p->fDataEccErr,
+                               &TRC_Status_p->fAdminEccErr);
+
+    // Read ARC4RC status
+    EIP207_RC_PARAMS_RD(Device,
+                        EIP207_ARC4RC_REG_BASE,
+                        CacheSetId,
+                        &ARC4RC_Status_p->fDMAReadError,
+                        &ARC4RC_Status_p->fDMAWriteError);
+
+    EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+                               EIP207_ARC4RC_REG_BASE,
+                               CacheSetId,
+                               &ARC4RC_Status_p->fDataEccOflo,
+                               &ARC4RC_Status_p->fDataEccErr,
+                               &ARC4RC_Status_p->fAdminEccErr);
+}
+
+
+/* end of file eip207_rc_internal.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c
new file mode 100644
index 0000000..b5982c6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c
@@ -0,0 +1,86 @@
+/* eip207_support.c
+ *
+ * EIP-207 Support interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Support interface
+#include "eip207_support.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                 // uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h"               // Device_Handle_t
+#include "device_rw.h"                  // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Read64
+ */
+EIP207_Global_Error_t
+EIP207_Global_Read64(
+        const Device_Handle_t Device,
+        const unsigned int Value64_OffsetLo,
+        const unsigned int Value64_OffsetHi,
+        EIP207_Global_Value64_t * const Value64_p)
+{
+    uint32_t Value32;
+    unsigned int i;
+
+    for (i = 0; i < EIP207_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS; i++)
+    {
+        Value32 = Device_Read32(Device, Value64_OffsetHi);
+
+        Value64_p->Value64_Lo = Device_Read32(Device, Value64_OffsetLo);
+        Value64_p->Value64_Hi = Device_Read32(Device, Value64_OffsetHi);
+
+        if (Value32 == Value64_p->Value64_Hi)
+            return EIP207_GLOBAL_NO_ERROR;
+    }
+
+    return EIP207_GLOBAL_INTERNAL_ERROR;
+}
+
+
+/* end of file eip207_support.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c
new file mode 100644
index 0000000..a9ef9ff
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c
@@ -0,0 +1,388 @@
+/* eip74.c
+ *
+ * Implementation of the EIP-74 Driver Library.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP76 initialization API
+#include "eip74.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+
+// EIP-76 Driver Library Internal interfaces
+#include "eip74_level0.h"       // Level 0 macros
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// I/O Area, used internally
+typedef struct
+{
+    Device_Handle_t Device;
+} EIP74_True_IOArea_t;
+
+#define TEST_SIZEOF(type, size) \
+    extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+
+#ifdef EIP74_STRICT_ARGS
+#define EIP74_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return EIP74_ARGUMENT_ERROR;
+#else
+/* EIP74_STRICT_ARGS undefined */
+#define EIP74_CHECK_POINTER(_p)
+#define EIP74_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP74_CHECK_INT_ATLEAST(_i, _min)
+#define EIP74_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP74_STRICT_ARGS */
+
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP74_True_IOArea_t, EIP74_IOAREA_REQUIRED_SIZE);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74Lib_Detect
+ *
+ * Checks the presence of EIP-74 device. Returns true when found.
+ */
+static bool
+EIP74Lib_Detect(
+        const Device_Handle_t Device)
+{
+    uint32_t Value;
+
+    Value = EIP74_Read32(Device, EIP74_REG_VERSION);
+    if (!EIP74_REV_SIGNATURE_MATCH( Value ))
+        return false;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74Lib_Reset_IsDone
+ */
+static bool
+EIP74Lib_Reset_IsDone(
+        const Device_Handle_t Device)
+{
+    bool fReady, fPSAIWriteOK, fStuckOut, fEarlyReseed;
+    bool fTestReady,fGenPktError, fInstantiated, fTestStuckOut, fNeedClock;
+    uint8_t BlocksAvailable;
+
+    EIP74_STATUS_RD(Device,
+                    &fReady,
+                    &fPSAIWriteOK,
+                    &fStuckOut,
+                    &fEarlyReseed,
+                    &fTestReady,
+                    &fGenPktError,
+                    &fInstantiated,
+                    &fTestStuckOut,
+                    &BlocksAvailable,
+                    &fNeedClock);
+
+    return fPSAIWriteOK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Init
+ */
+EIP74_Error_t
+EIP74_Init(
+        EIP74_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+
+    TrueIOArea_p->Device = Device;
+
+    if (!EIP74Lib_Detect(Device))
+    {
+        return EIP74_UNSUPPORTED_FEATURE_ERROR;
+    }
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset
+ */
+EIP74_Error_t
+EIP74_Reset(
+        EIP74_IOArea_t * const IOArea_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_CONTROL_WR(Device,
+                     false, /* fReadyMask */
+                     false, /* fStuckOut */
+                     false, /* fTestMode */
+                     false, /* fHostMode */
+                     false, /* fEnableDRBG */
+                     false, /* fForceStuckOut */
+                     false, /* fRequestdata */
+                     0); /* DataBlocks */
+
+    if (EIP74Lib_Reset_IsDone(Device))
+    {
+        return EIP74_NO_ERROR;
+    }
+    else
+    {
+        return EIP74_BUSY_RETRY_LATER;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset_IsDone
+ */
+EIP74_Error_t
+EIP74_Reset_IsDone(
+        EIP74_IOArea_t * const IOArea_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    if (EIP74Lib_Reset_IsDone(Device))
+    {
+        return EIP74_NO_ERROR;
+    }
+    else
+    {
+        return EIP74_BUSY_RETRY_LATER;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_HWRevision_Get
+  */
+EIP74_Error_t
+EIP74_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP74_Capabilities_t * const Capabilities_p)
+{
+    EIP74_CHECK_POINTER(Capabilities_p);
+
+    EIP74_VERSION_RD(Device,
+                     &Capabilities_p->HW_Revision.EipNumber,
+                     &Capabilities_p->HW_Revision.ComplmtEipNumber,
+                     &Capabilities_p->HW_Revision.HWPatchLevel,
+                     &Capabilities_p->HW_Revision.MinHWRevision,
+                     &Capabilities_p->HW_Revision.MajHWRevision);
+    EIP74_OPTIONS_RD(Device,
+                     &Capabilities_p->HW_Options.ClientCount,
+                     &Capabilities_p->HW_Options.AESCoreCount,
+                     &Capabilities_p->HW_Options.AESSpeed,
+                     &Capabilities_p->HW_Options.FIFODepth);
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Configure
+ */
+EIP74_Error_t
+EIP74_Configure(
+        EIP74_IOArea_t * const IOArea_p,
+        const EIP74_Configuration_t * const Configuration_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+    EIP74_CHECK_POINTER(Configuration_p);
+    EIP74_CHECK_INT_INRANGE(Configuration_p->GenerateBlockSize, 1, 4095);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_GEN_BLK_SIZE_WR(Device, Configuration_p->GenerateBlockSize);
+    EIP74_RESEED_THR_WR(Device, Configuration_p->ReseedThr);
+    EIP74_RESEED_THR_EARLY_WR(Device, Configuration_p->ReseedThrEarly);
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Instantiate
+ */
+EIP74_Error_t
+EIP74_Instantiate(
+        EIP74_IOArea_t * const IOArea_p,
+        const uint32_t * const Entropy_p,
+        bool fStuckOut)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+    EIP74_CHECK_POINTER(Entropy_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_PS_AI_WR(Device, Entropy_p, 12);
+
+    EIP74_CONTROL_WR(Device,
+                     false, /* fReadyMask */
+                     fStuckOut,
+                     false, /* fTestMode */
+                     false, /* fHostMode */
+                     true, /* fEnableDRBG */
+                     false, /* fForceStuckOut */
+                     false, /* fRequestdata */
+                     0); /* DataBlocks */
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reseed
+ */
+EIP74_Error_t
+EIP74_Reseed(
+        EIP74_IOArea_t * const IOArea_p,
+        const uint32_t * const Entropy_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+    EIP74_CHECK_POINTER(Entropy_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_PS_AI_WR(Device, Entropy_p, 12);
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Status_Get
+ */
+EIP74_Error_t
+EIP74_Status_Get(
+        EIP74_IOArea_t * const IOArea_p,
+        EIP74_Status_t * const Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    bool fReady, fPSAIWriteOK, fStuckOut, fEarlyReseed;
+    bool fTestReady,fGenPktError, fInstantiated, fTestStuckOut, fNeedClock;
+    uint8_t BlocksAvailable;
+    uint32_t GenBlockCount, ReseedThr;
+    EIP74_CHECK_POINTER(IOArea_p);
+    EIP74_CHECK_POINTER(Status_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_STATUS_RD(Device,
+                    &fReady,
+                    &fPSAIWriteOK,
+                    &fStuckOut,
+                    &fEarlyReseed,
+                    &fTestReady,
+                    &fGenPktError,
+                    &fInstantiated,
+                    &fTestStuckOut,
+                    &BlocksAvailable,
+                    &fNeedClock);
+
+    EIP74_GENERATE_CNT_RD(Device, &GenBlockCount);
+    EIP74_RESEED_THR_RD(Device, &ReseedThr);
+
+    Status_p->GenerateBlockCount = GenBlockCount;
+    Status_p->fStuckOut = fStuckOut;
+    Status_p->fNotInitialized = fGenPktError;
+    Status_p->fReseedError = GenBlockCount == ReseedThr;
+    Status_p->fReseedWarning = fEarlyReseed;
+    Status_p->fInstantiated = fInstantiated;
+    Status_p->AvailableCount = BlocksAvailable;
+
+    return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Clear
+ */
+EIP74_Error_t
+EIP74_Clear(
+        EIP74_IOArea_t * const IOArea_p)
+{
+    Device_Handle_t Device;
+    volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+        (EIP74_True_IOArea_t *)IOArea_p;
+    EIP74_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP74_INTACK_WR(Device, false, true, false);
+
+    return EIP74_NO_ERROR;
+}
+
+
+/* end of file eip74.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c
new file mode 100644
index 0000000..cf47963
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c
@@ -0,0 +1,409 @@
+/* eip97_global_event.c
+ *
+ * EIP-97 Global Control Driver Library
+ * Event Management Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_event.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // uint32_t
+
+// Driver Framework Device API
+#include "device_types.h"              // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip202_global_level0.h"      // EIP-202 Level 0 macros
+#include "eip96_level0.h"              // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h"          // State machine
+#include "eip97_global_level0.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+#ifdef EIP97_REG_DBG_BASE
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Debug_Statistics_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_Debug_Statistics_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        EIP97_Global_Debug_Statistics_t * const Debug_Statistics_p)
+{
+    Device_Handle_t Device;
+    unsigned int i;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(Debug_Statistics_p);
+
+    Device = TrueIOArea_p->Device;
+
+    for (i = 0; i < 16; i++)
+    {
+        EIP97_DBG_RING_IN_COUNT_RD(Device,
+                                   i,
+                                   &Debug_Statistics_p->Ifc_Packets_In[i]);
+        EIP97_DBG_RING_OUT_COUNT_RD(Device,
+                                    i,
+                                    &Debug_Statistics_p->Ifc_Packets_Out[i]);
+
+    }
+    for (i = 0; i < EIP97_GLOBAL_MAX_NOF_PE_TO_USE; i++)
+    {
+        EIP97_DBG_PIPE_COUNT_RD(Device,
+                                i,
+                                &Debug_Statistics_p->Pipe_Total_Packets[i],
+                                &Debug_Statistics_p->Pipe_Current_Packets[i],
+                                &Debug_Statistics_p->Pipe_Max_Packets[i]);
+        EIP97_DBG_PIPE_DCOUNT_RD(Device,
+                                 i,
+                                 &Debug_Statistics_p->Pipe_Data_Count[i]);
+    }
+    for (i = EIP97_GLOBAL_MAX_NOF_PE_TO_USE; i < 16; i++)
+    {
+        Debug_Statistics_p->Pipe_Total_Packets[i] = 0;
+        Debug_Statistics_p->Pipe_Current_Packets[i] = 0;
+        Debug_Statistics_p->Pipe_Max_Packets[i] = 0;
+        Debug_Statistics_p->Pipe_Data_Count[i] = 0;
+    }
+    return 0;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DFE_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_DFE_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP97_Global_DFE_Status_t * const DFE_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    unsigned int DFEDSEOffset;
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(DFE_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202_DFE_TRD_STAT_RD(Device,
+                           DFEDSEOffset,
+                           PE_Number,
+                           &DFE_Status_p->CDFifoWord32Count,
+                           &DFE_Status_p->CDR_ID,
+                           &DFE_Status_p->DMASize,
+                           &DFE_Status_p->fAtDMABusy,
+                           &DFE_Status_p->fDataDMABusy,
+                           &DFE_Status_p->fDMAError);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        if(DFE_Status_p->fDMAError)
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    EIP97_GLOBAL_STATE_FATAL_ERROR);
+        else
+            // Remain in the current state
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DSE_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_DSE_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP97_Global_DSE_Status_t * const DSE_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    unsigned int DFEDSEOffset;
+    DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(DSE_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202_DSE_TRD_STAT_RD(Device,
+                           DFEDSEOffset,
+                           PE_Number,
+                           &DSE_Status_p->RDFifoWord32Count,
+                           &DSE_Status_p->RDR_ID,
+                           &DSE_Status_p->DMASize,
+                           &DSE_Status_p->fDataFlushBusy,
+                           &DSE_Status_p->fDataDMABusy,
+                           &DSE_Status_p->fDMAError);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        if(DSE_Status_p->fDMAError)
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    EIP97_GLOBAL_STATE_FATAL_ERROR);
+        else
+            // Remain in the current state
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Token_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Token_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Token_Status_t * const Token_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(Token_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        // Remain in the current state
+        rv = EIP97_Global_State_Set(
+                (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    EIP96_TOKEN_CTRL_STAT_RD(Device,
+                             PE_Number,
+                             &Token_Status_p->ActiveTokenCount,
+                             &Token_Status_p->fTokenLocationAvailable,
+                             &Token_Status_p->fResultTokenAvailable,
+                             &Token_Status_p->fTokenReadActive,
+                             &Token_Status_p->fContextCacheActive,
+                             &Token_Status_p->fContextFetch,
+                             &Token_Status_p->fResultContext,
+                             &Token_Status_p->fProcessingHeld,
+                             &Token_Status_p->fBusy);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Context_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Context_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Context_Status_t * const Context_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(Context_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    EIP96_CONTEXT_STAT_RD(Device,
+                          PE_Number,
+                          &Context_Status_p->Error,
+                          &Context_Status_p->AvailableTokenCount,
+                          &Context_Status_p->fActiveContext,
+                          &Context_Status_p->fNextContext,
+                          &Context_Status_p->fResultContext,
+                          &Context_Status_p->fErrorRecovery);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        if((Context_Status_p->Error & EIP96_TIMEOUT_FATAL_ERROR_MASK) != 0)
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    EIP97_GLOBAL_STATE_FATAL_ERROR);
+        else
+            // Remain in the current state
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_OutXfer_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_OutXfer_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_Output_Transfer_Status_t * const OutXfer_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(OutXfer_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        // Remain in the current state
+        rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    EIP96_OUT_TRANS_CTRL_STAT_RD(Device,
+                                 PE_Number,
+                                 &OutXfer_Status_p->AvailableWord32Count,
+                                 &OutXfer_Status_p->MinTransferWordCount,
+                                 &OutXfer_Status_p->MaxTransferWordCount,
+                                 &OutXfer_Status_p->TransferSizeMask);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_PRNG_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_PRNG_Status_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        EIP96_PRNG_Status_t * const PRNG_Status_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(PRNG_Status_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        // Remain in the current state
+        rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    EIP96_PRNG_STAT_RD(Device,
+                       PE_Number,
+                       &PRNG_Status_p->fBusy,
+                       &PRNG_Status_p->fResultReady);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c
new file mode 100644
index 0000000..e3f5ffb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c
@@ -0,0 +1,164 @@
+/* eip97_global_fsm.c
+ *
+ * EIP-97 Global Control Driver Library API State Machine Internal Interface
+ * implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-97 Driver Library Types API
+#include "eip97_global_types.h"        // EIP97_Global_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_State_Set
+ *
+ */
+EIP97_Global_Error_t
+EIP97_Global_State_Set(
+        volatile EIP97_Global_State_t * const CurrentState,
+        const EIP97_Global_State_t NewState)
+{
+    switch(*CurrentState)
+    {
+        case EIP97_GLOBAL_STATE_UNKNOWN:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_SW_RESET_START:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+         case EIP97_GLOBAL_STATE_HW_RESET_DONE:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_INITIALIZED:
+                   *CurrentState = NewState;
+                   break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP97_GLOBAL_STATE_SW_RESET_START:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_SW_RESET_START:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                case EIP97_GLOBAL_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP97_GLOBAL_STATE_INITIALIZED:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_ENABLED:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_INITIALIZED:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP97_GLOBAL_STATE_ENABLED:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_SW_RESET_START:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_FATAL_ERROR:
+                    break;
+                case EIP97_GLOBAL_STATE_ENABLED:
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        case EIP97_GLOBAL_STATE_FATAL_ERROR:
+            switch(NewState)
+            {
+                case EIP97_GLOBAL_STATE_SW_RESET_START:
+                    *CurrentState = NewState;
+                    break;
+                case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+                    *CurrentState = NewState;
+                    break;
+                default:
+                    return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+            }
+            break;
+
+        default:
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c
new file mode 100644
index 0000000..4289875
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c
@@ -0,0 +1,68 @@
+/* eip97_global_fsm_stub.c
+ *
+ * EIP-97 Global Control Driver Library API State Machine Internal Interface
+ * stub implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"                // IDENTIFIER_NOT_USED
+
+// EIP-97 Driver Library Types API
+#include "eip97_global_types.h"        // EIP97_Global_* types
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_State_Set
+ *
+ */
+EIP97_Global_Error_t
+EIP97_Global_State_Set(
+        EIP97_Global_State_t * const CurrentState,
+        const EIP97_Global_State_t NewState)
+{
+    IDENTIFIER_NOT_USED(CurrentState);
+    IDENTIFIER_NOT_USED((bool)NewState);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_fsm_stub.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c
new file mode 100644
index 0000000..5f060cb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c
@@ -0,0 +1,827 @@
+/* eip97_global_init.c
+ *
+ * EIP-97 Global Control Driver Library
+ * Initialization Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h"                       // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h"           // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip97_global_level0.h"       // EIP-97 Level 0 macros
+#include "eip202_global_init.h"        // EIP-202 Initialization code
+#include "eip206_level0.h"             // EIP-206 Level 0 macros
+#include "eip96_level0.h"              // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h"          // State machine
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum number of Packet Engines that should be used
+// Driver Library will check the maximum number supported run-time
+#ifndef EIP97_GLOBAL_MAX_NOF_PE_TO_USE
+#error "EIP97_GLOBAL_MAX_NOF_PE_TO_USE is not defined"
+#endif
+
+// Number of Ring interfaces
+// Maximum number of Ring interfaces that should be used
+// Driver Library will check the maximum number supported run-time
+#ifndef EIP97_GLOBAL_MAX_NOF_RING_TO_USE
+#error "EIP97_GLOBAL_MAX_NOF_RING_TO_USE is not defined"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static unsigned int Global97_NofPEs;
+static unsigned int Global97_NofRings;
+static unsigned int Global97_NofLA;
+static unsigned int Global97_NofIN;
+static unsigned int Global97_DFEDSEOffset;
+static unsigned int Global97_SupportedFuncs;
+
+/*----------------------------------------------------------------------------
+ * EIP206Lib_Detect
+ *
+ * Checks the presence of EIP-206 PE hardware. Returns true when found.
+ */
+static bool
+EIP206Lib_Detect(
+        const Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    uint32_t Value;
+
+    // No revision register for this HW version
+
+    // read-write test one of the registers
+
+    // Set MASK_8_BITS bits of the EIP206_OUT_REG_DBUF_TRESH register
+    EIP206_Write32(Device,
+                   EIP206_OUT_REG_DBUF_TRESH(PEnr),
+                   MASK_8_BITS);
+    Value = EIP206_Read32(Device,
+                          EIP206_OUT_REG_DBUF_TRESH(PEnr));
+    if ((Value & MASK_8_BITS) != MASK_8_BITS)
+        return false;
+
+    // Clear MASK_8_BITS bits of the EIP206_OUT_REG_DBUF_TRESH(PEnr) register
+    EIP206_Write32(Device, EIP206_OUT_REG_DBUF_TRESH(PEnr), 0);
+    Value = EIP206_Read32(Device, EIP206_OUT_REG_DBUF_TRESH(PEnr));
+    if ((Value & MASK_8_BITS) != 0)
+       return false;
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP96Lib_Detect
+ *
+ * Checks the presence of EIP-96 Engine hardware. Returns true when found.
+ */
+static bool
+EIP96Lib_Detect(
+        const Device_Handle_t Device,
+        const unsigned int PEnr)
+{
+    uint32_t Value, DefaultValue;
+    bool fSuccess = true;
+
+    // No revision register for this HW version
+
+    // Save the default register value
+    DefaultValue = EIP96_Read32(Device,
+                                EIP96_REG_CONTEXT_CTRL(PEnr));
+
+    // read-write test one of the registers
+
+    // Set MASK_6_BITS bits of the EIP96_REG_CONTEXT_CTRL register
+    EIP96_Write32(Device,
+                  EIP96_REG_CONTEXT_CTRL(PEnr),
+                  MASK_6_BITS );
+    Value = EIP96_Read32(Device, EIP96_REG_CONTEXT_CTRL(PEnr));
+    if ((Value & MASK_6_BITS) != MASK_6_BITS)
+        fSuccess = false;
+
+    if( fSuccess )
+    {
+        // Clear MASK_6_BITS bits of the EIP96_REG_CONTEXT_CTRL register
+        EIP96_Write32(Device, EIP96_REG_CONTEXT_CTRL(PEnr), 0);
+        Value = EIP96_Read32(Device, EIP96_REG_CONTEXT_CTRL(PEnr));
+        if ((Value & MASK_6_BITS) != 0)
+            fSuccess = false;
+    }
+
+    // Restore the default register value
+    EIP96_Write32(Device,
+            EIP96_REG_CONTEXT_CTRL(PEnr),
+                  DefaultValue );
+    return fSuccess;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_Detect
+ *
+ * Checks the presence of EIP-97 Engine hardware. Returns true when found.
+ */
+static bool
+EIP97Lib_Detect(
+        const Device_Handle_t Device)
+{
+#ifdef EIP97_GLOBAL_VERSION_CHECK_ENABLE
+    uint32_t Value;
+
+    // read and check the revision register
+    Value = EIP97_Read32(Device, EIP97_REG_VERSION);
+    if (!EIP97_REV_SIGNATURE_MATCH( Value ))
+        return false;
+#else
+    IDENTIFIER_NOT_USED(Device);
+#endif // EIP97_GLOBAL_VERSION_CHECK_ENABLE
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_HWRevision_Get
+ */
+static void
+EIP202Lib_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP202_Options_t * const Options_p,
+        EIP202_Options2_t * const Options2_p,
+        EIP_Version_t * const Version_p)
+{
+    EIP202_Capabilities_t EIP202_Capabilities;
+    EIP202_Global_HWRevision_Get(Device, &EIP202_Capabilities);
+
+    Version_p->EipNumber = EIP202_Capabilities.EipNumber;
+    Version_p->ComplmtEipNumber = EIP202_Capabilities.ComplmtEipNumber;
+    Version_p->HWPatchLevel = EIP202_Capabilities.HWPatchLevel;
+    Version_p->MinHWRevision = EIP202_Capabilities.MinHWRevision;
+    Version_p->MajHWRevision = EIP202_Capabilities.MajHWRevision;
+
+    Options_p->NofRings = EIP202_Capabilities.NofRings;
+    Options_p->NofPes = EIP202_Capabilities.NofPes;
+    Options_p->fExpPlf = EIP202_Capabilities.fExpPlf;
+    Options_p->CF_Size = EIP202_Capabilities.CF_Size;
+    Options_p->RF_Size = EIP202_Capabilities.RF_Size;
+    Options_p->HostIfc = EIP202_Capabilities.HostIfc;
+    Options_p->DMA_Len = EIP202_Capabilities.DMA_Len;
+    Options_p->HDW = EIP202_Capabilities.HDW;
+    Options_p->TgtAlign = EIP202_Capabilities.TgtAlign;
+    Options_p->fAddr64 = EIP202_Capabilities.fAddr64;
+
+    Options2_p->NofLA_Ifs = EIP202_Capabilities.NofLA_Ifs;
+    Options2_p->NofIN_Ifs = EIP202_Capabilities.NofIN_Ifs;
+    Options2_p->NofAXI_WrChs = EIP202_Capabilities.NofAXI_WrChs;
+    Options2_p->NofAXI_RdClusters = EIP202_Capabilities.NofAXI_RdClusters;
+    Options2_p->NofAXI_RdCPC = EIP202_Capabilities.NofAXI_RdCPC;
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP96Lib_HWRevision_Get
+ */
+static void
+EIP96Lib_HWRevision_Get(
+        const Device_Handle_t Device,
+        const unsigned int PEnr,
+        EIP96_Options_t * const Options_p,
+        EIP_Version_t * const Version_p)
+{
+    uint32_t OptionsVal;
+    EIP96_EIP_REV_RD(Device,
+                     PEnr,
+                     &Version_p->EipNumber,
+                     &Version_p->ComplmtEipNumber,
+                     &Version_p->HWPatchLevel,
+                     &Version_p->MinHWRevision,
+                     &Version_p->MajHWRevision);
+
+    EIP96_OPTIONS_RD(Device,
+                     PEnr,
+                     &Options_p->fAES,
+                     &Options_p->fAESfb,
+                     &Options_p->fAESspeed,
+                     &Options_p->fDES,
+                     &Options_p->fDESfb,
+                     &Options_p->fDESspeed,
+                     &Options_p->ARC4,
+                     &Options_p->fAES_XTS,
+                     &Options_p->fWireless,
+                     &Options_p->fMD5,
+                     &Options_p->fSHA1,
+                     &Options_p->fSHA1speed,
+                     &Options_p->fSHA224_256,
+                     &Options_p->fSHA384_512,
+                     &Options_p->fXCBC_MAC,
+                     &Options_p->fCBC_MACspeed,
+                     &Options_p->fCBC_MACkeylens,
+                     &Options_p->fGHASH);
+    Global97_SupportedFuncs = Device_Read32(Device, EIP96_REG_OPTIONS(0)) & 0xfffffff0;
+    OptionsVal = Device_Read32(Device, EIP97_REG_OPTIONS);
+    if ((OptionsVal & BIT_30) != 0)
+    {
+        Global97_SupportedFuncs |= BIT_3;
+    }
+    if ((OptionsVal & BIT_25) != 0)
+    {
+        Global97_SupportedFuncs |= BIT_2;
+    }
+    if ((OptionsVal & BIT_24) != 0)
+    {
+        Global97_SupportedFuncs |= BIT_1;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_HWRevision_Get
+ */
+static void
+EIP97Lib_HWRevision_Get(
+        const Device_Handle_t Device,
+        EIP97_Options_t * const Options_p,
+        EIP_Version_t * const Version_p)
+{
+    EIP97_EIP_REV_RD(Device,
+                     &Version_p->EipNumber,
+                     &Version_p->ComplmtEipNumber,
+                     &Version_p->HWPatchLevel,
+                     &Version_p->MinHWRevision,
+                     &Version_p->MajHWRevision);
+
+    EIP97_OPTIONS_RD(Device,
+                     &Options_p->NofPes,
+                     &Options_p->in_tbuf_size,
+                     &Options_p->in_dbuf_size,
+                     &Options_p->out_tbuf_size,
+                     &Options_p->out_dbuf_size,
+                     &Options_p->central_prng,
+                     &Options_p->tg,
+                     &Options_p->trc);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_Reset_IsDone
+ */
+static EIP97_Global_Error_t
+EIP97Lib_Reset_IsDone(
+        const Device_Handle_t Device,
+        volatile uint32_t * State_p,
+        const unsigned int PEnr)
+{
+    bool fResetDone = EIP202_Global_Reset_IsDone(Device, PEnr);
+
+    if(fResetDone)
+    {
+        // Transit to a new state
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+        {
+            EIP97_Global_Error_t rv;
+
+            rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)State_p,
+                                        EIP97_GLOBAL_STATE_SW_RESET_DONE);
+            if(rv != EIP97_GLOBAL_NO_ERROR)
+                return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+        }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+    }
+    else
+    {
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+        {
+            EIP97_Global_Error_t rv;
+
+            // SW Reset is ongoing, retry later
+            rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)State_p,
+                                        EIP97_GLOBAL_STATE_SW_RESET_START);
+            if(rv != EIP97_GLOBAL_NO_ERROR)
+                return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+        }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+        return EIP97_GLOBAL_BUSY_RETRY_LATER;
+    }
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Init
+ */
+EIP97_Global_Error_t
+EIP97_Global_Init(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    unsigned int i;
+    EIP97_Global_Capabilities_t Capabilities;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    ZEROINIT(Capabilities);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+    // Attempt to initialize slave byte swapping.
+    if (!EIP202_Global_Endianness_Slave_Configure(Device))
+        return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    // Detect presence of the EIP-97 HW hardware
+    if (!EIP202_Global_Detect(Device) ||
+        !EIP206Lib_Detect(Device, PE_DEFAULT_NR) ||
+        !EIP96Lib_Detect(Device, PE_DEFAULT_NR) ||
+        !EIP97Lib_Detect(Device))
+        return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    // Initialize the IO Area
+    TrueIOArea_p->Device = Device;
+    // Can also be EIP97_GLOBAL_STATE_HW_RESET_DONE
+    TrueIOArea_p->State = (uint32_t)EIP97_GLOBAL_STATE_SW_RESET_DONE;
+
+    EIP97Lib_HWRevision_Get(Device,
+                            &Capabilities.EIP97_Options,
+                            &Capabilities.EIP97_Version);
+
+    EIP202Lib_HWRevision_Get(Device,
+                             &Capabilities.EIP202_Options,
+                             &Capabilities.EIP202_Options2,
+                             &Capabilities.EIP202_Version);
+
+    EIP96Lib_HWRevision_Get(Device,
+                            PE_DEFAULT_NR,
+                            &Capabilities.EIP96_Options,
+                            &Capabilities.EIP96_Version);
+
+    // Check actual configuration HW against capabilities
+    // Number of configured PE's
+    Global97_NofPEs = MIN(Capabilities.EIP202_Options.NofPes,
+                          EIP97_GLOBAL_MAX_NOF_PE_TO_USE);
+
+    // Number of configure ring interfaces
+    Global97_NofRings = MIN(Capabilities.EIP202_Options.NofRings,
+                            EIP97_GLOBAL_MAX_NOF_RING_TO_USE);
+
+    // Number of configured Look-aside FIFO interfaces
+#if EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE==0
+    Global97_NofLA = 0;
+#else
+    Global97_NofLA = MIN(Capabilities.EIP202_Options2.NofLA_Ifs,
+                         EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE);
+#endif
+#if EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE==0
+    Global97_NofIN = 0;
+#else
+    // Number of configured Inline FIFO interfaces
+    Global97_NofIN = MIN(Capabilities.EIP202_Options2.NofIN_Ifs,
+                         EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE);
+#endif
+
+    // EIP197 devices with more than 12 rings move the
+    // DFE and DSE register addresses up by 2*4kB to make room for 2 extra
+    // sets of ring control registers.
+    if (Capabilities.EIP202_Options.NofRings > 12)
+    {
+        Global97_DFEDSEOffset = 0x2000;
+    }
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+        {
+            EIP97_Global_Error_t rv;
+
+            // Transit to a new state
+            rv = EIP97_Global_State_Set(
+                    (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                    EIP97_GLOBAL_STATE_INITIALIZED);
+            if(rv != EIP97_GLOBAL_NO_ERROR)
+                return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+        }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    // Configure Endianness Conversion method for master (DMA) interface
+    for (i = 0; i < Global97_NofPEs; i++)
+        EIP97_MST_CTRL_WR(Device,
+                          i,
+                          EIP97_GLOBAL_RD_CACHE_VALUE,
+                          EIP97_GLOBAL_WR_CACHE_VALUE,
+                          EIP97_GLOBAL_BYTE_SWAP_METHOD,
+                          EIP97_GLOBAL_SUPPORT_PROTECT_VALUE,
+                          0,  // Disable cache-aligned context writes.
+                          false);
+    {
+        uint8_t ipbuf_max, ipbuf_min,
+                itbuf_max, itbuf_min,
+                opbuf_max, opbuf_min;
+
+#ifdef EIP97_GLOBAL_THRESH_CONFIG_AUTO
+        // Calculate the EIP-202 and EIP-206 Global Control thresholds
+        uint8_t dmalen;
+
+        // Convert to powers of byte counts from powers of 32-bit word counts
+        ipbuf_max = Capabilities.EIP97_Options.in_dbuf_size + 2;
+        itbuf_max = Capabilities.EIP97_Options.in_tbuf_size + 2;
+        opbuf_max = Capabilities.EIP97_Options.out_dbuf_size + 2;
+
+        // EIP-96 token cannot be larger than 2^7 bytes
+        if( itbuf_max > EIP97_GLOBAL_MAX_TOKEN_SIZE )
+            itbuf_max = EIP97_GLOBAL_MAX_TOKEN_SIZE;
+
+        // DMA_Len is power of byte count
+        if (Capabilities.EIP202_Options.DMA_Len >= 1)
+            dmalen = Capabilities.EIP202_Options.DMA_Len - 1;
+        else
+            dmalen = Capabilities.EIP202_Options.DMA_Len;
+
+        ipbuf_max = MIN(ipbuf_max, dmalen);
+        itbuf_max = MIN(itbuf_max, dmalen);
+        opbuf_max = MIN(opbuf_max, dmalen);
+
+        ipbuf_min = ipbuf_max - 1;
+        itbuf_min = itbuf_max - 1;
+        opbuf_min = opbuf_max - 1;
+#else
+        // Use configured statically
+        // the EIP-202 and EIP-206 Global Control thresholds
+        ipbuf_min = EIP97_GLOBAL_DFE_MIN_DATA_XFER_SIZE;
+        ipbuf_max = EIP97_GLOBAL_DFE_MAX_DATA_XFER_SIZE;
+
+        itbuf_min = EIP97_GLOBAL_DFE_MIN_TOKEN_XFER_SIZE;
+        itbuf_max = EIP97_GLOBAL_DFE_MAX_TOKEN_XFER_SIZE;
+
+        opbuf_min = EIP97_GLOBAL_DSE_MIN_DATA_XFER_SIZE;
+        opbuf_max = EIP97_GLOBAL_DSE_MAX_DATA_XFER_SIZE;
+#endif
+
+        EIP202_Global_Init(Device,
+                           Global97_NofPEs,
+                           Capabilities.EIP202_Options2.NofLA_Ifs,
+                           ipbuf_min,
+                           ipbuf_max,
+                           itbuf_min,
+                           itbuf_max,
+                           opbuf_min,
+                           opbuf_max);
+        for (i = 0; i < Global97_NofPEs; i++)
+        {
+
+            // Configure EIP-206 Processing Engine
+            EIP206_IN_DBUF_THRESH_WR(
+                            Device,
+                            i,
+                            0,
+                            ipbuf_min,
+                            ipbuf_max); // ... or use 0xF for maximum, autoconf
+
+            EIP206_IN_TBUF_THRESH_WR(
+                            Device,
+                            i,
+                            EIP97_GLOBAL_IN_TBUF_PKT_THR,
+                            itbuf_min,
+                            itbuf_max); // ... or use 0xF for maximum, autoconf
+
+            EIP206_OUT_DBUF_THRESH_WR(
+                            Device,
+                            i,
+                            opbuf_min,
+                            opbuf_max); // ... or use 0xF for maximum, autoconf
+
+            // Configure EIP-96 Packet Engine
+            EIP96_TOKEN_CTRL_STAT_WR(
+                    Device,
+                    i,
+                    true, /* optimal context update */
+                    EIP97_GLOBAL_EIP96_NO_TOKEN_WAIT, /* CT No token wait */
+                    false, /* Absulute ARC4 pointer */
+                    false, /* Allow reuse cached context */
+                    false, /* Allow postponed reuse */
+                    false, /* Zero length result */
+                    (EIP97_GLOBAL_EIP96_TIMEOUT_CNTR_FLAG == 0) ? false : true,
+                    (EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE == 0) ? false : true
+                    );
+            EIP96_TOKEN_CTRL2_WR(
+                    Device,
+                    i,
+                    true,
+                    true,
+                    false,
+                    EIP97_GLOBAL_EIP96_CTX_DONE_PULSE);
+            EIP96_OUT_BUF_CTRL_WR(
+                    Device,
+                    i,
+                    EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA,
+                    (EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND == 0) ? false : true,
+                    (EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE == 0) ? false : true);
+            EIP96_CONTEXT_CTRL_WR(
+                Device,
+                i,
+                EIP97_EIP96_CTX_SIZE,
+                false,
+                true);
+            EIP96_CTX_NUM32_THR_WR(
+                Device,
+                i,
+                EIP97_GLOBAL_EIP96_NUM32_THR);
+            EIP96_CTX_NUM64_THR_L_WR(
+                Device,
+                i,
+                EIP97_GLOBAL_EIP96_NUM64_THR_L);
+            EIP96_CTX_NUM64_THR_H_WR(
+                Device,
+                i,
+                EIP97_GLOBAL_EIP96_NUM64_THR_H);
+#ifdef EIP97_GLOBAL_HAVE_ECN_FIXUP
+            EIP96_ECN_TABLE_WR(Device, i, 0,
+                               0, 0,
+                               1, 0,
+                               2, 0,
+                               3, 0);
+            EIP96_ECN_TABLE_WR(Device, i, 1,
+                               0, EIP96_ECN_CLE0,
+                               1, 0,
+                               1, 0,
+                               3, EIP96_ECN_CLE1);
+            EIP96_ECN_TABLE_WR(Device, i, 2,
+                               0, EIP96_ECN_CLE2,
+                               1, EIP96_ECN_CLE3,
+                               2, 0,
+                               3, 0);
+            EIP96_ECN_TABLE_WR(Device, i, 3,
+                               0, EIP96_ECN_CLE4,
+                               3, 0,
+                               3, 0,
+                               3, 0);
+#endif
+        } // for
+
+    } // EIP-202 HIA Global is configured
+
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const Device_Handle_t Device)
+{
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    unsigned int i;
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+    // Attempt to initialize slave byte swapping.
+    if (!EIP202_Global_Endianness_Slave_Configure(Device))
+        return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    // Initialize the IO Area
+    TrueIOArea_p->Device = Device;
+    // Assume this function is called in the Unknown state but
+    // this may not always be true
+    TrueIOArea_p->State = (uint32_t)EIP97_GLOBAL_STATE_UNKNOWN;
+
+    if (!EIP202_Global_Reset(Device, Global97_NofPEs))
+        return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+    for (i = 0; i < Global97_NofPEs; i++)
+    {
+        // Restore the EIP-206 default configuration
+        EIP206_IN_DBUF_THRESH_DEFAULT_WR(Device, i);
+        EIP206_IN_TBUF_THRESH_DEFAULT_WR(Device, i);
+        EIP206_OUT_DBUF_THRESH_DEFAULT_WR(Device, i);
+        EIP206_OUT_TBUF_THRESH_DEFAULT_WR(Device, i);
+
+        // Restore the EIP-96 default configuration
+        EIP96_TOKEN_CTRL_STAT_DEFAULT_WR(Device, i);
+    }
+
+    // Check if Global SW Reset is done
+    for (i = 0; i < Global97_NofPEs; i++)
+    {
+        EIP97_Global_Error_t EIP97_Rc;
+
+        EIP97_Rc =
+            EIP97Lib_Reset_IsDone(Device, &TrueIOArea_p->State, i);
+
+        if (EIP97_Rc != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_Rc;
+    }
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset_IsDone
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset_IsDone(
+        EIP97_Global_IOArea_t * const IOArea_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    unsigned int i;
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+    Device = TrueIOArea_p->Device;
+
+    // Check if Global SW Reset is done
+    for (i = 0; i < Global97_NofPEs; i++)
+    {
+        EIP97_Global_Error_t EIP97_Rc;
+
+        EIP97_Rc =
+            EIP97Lib_Reset_IsDone(Device, &TrueIOArea_p->State, i);
+
+        if (EIP97_Rc != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_Rc;
+    }
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_HWRevision_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_HWRevision_Get(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        EIP97_Global_Capabilities_t * const Capabilities_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(Capabilities_p);
+
+    Device = TrueIOArea_p->Device;
+
+    EIP202Lib_HWRevision_Get(Device,
+                             &Capabilities_p->EIP202_Options,
+                             &Capabilities_p->EIP202_Options2,
+                             &Capabilities_p->EIP202_Version);
+
+    EIP96Lib_HWRevision_Get(Device,
+                            PE_DEFAULT_NR,
+                            &Capabilities_p->EIP96_Options,
+                            &Capabilities_p->EIP96_Version);
+
+    EIP97Lib_HWRevision_Get(Device,
+                            &Capabilities_p->EIP97_Options,
+                            &Capabilities_p->EIP97_Version);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Configure
+ */
+EIP97_Global_Error_t
+EIP97_Global_Configure(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        const EIP97_Global_Ring_PE_Map_t * const RingPEMap_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+    EIP202_Global_Ring_PE_Map_t EIP202RingPEMap;
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+    EIP97_GLOBAL_CHECK_POINTER(RingPEMap_p);
+
+    if(PE_Number >= Global97_NofPEs)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+    // Figure out which rings must be assigned to
+    // DFE and DSE threads for PE_Number
+    EIP202RingPEMap.RingPE_Mask = (uint16_t)(RingPEMap_p->RingPE_Mask &
+                                             ((1 << (Global97_NofRings + Global97_NofLA + Global97_NofIN))-1));
+    EIP202RingPEMap.RingPrio_Mask = RingPEMap_p->RingPrio_Mask;
+    EIP202RingPEMap.RingSlots0 = RingPEMap_p->RingSlots0;
+    EIP202RingPEMap.RingSlots1 = RingPEMap_p->RingSlots1;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+        EIP97_Global_State_t NewState;
+
+        // Transit to a new state
+        if(EIP202RingPEMap.RingPE_Mask != 0)
+            NewState = EIP97_GLOBAL_STATE_ENABLED;
+        else
+            // Engines without rings not allowed!
+            NewState = EIP97_GLOBAL_STATE_INITIALIZED;
+
+        rv = EIP97_Global_State_Set(
+                (volatile EIP97_Global_State_t*)&TrueIOArea_p->State, NewState);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    EIP202_Global_Configure(Device, PE_Number, &EIP202RingPEMap);
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Interfaces_Get
+ */
+void
+EIP97_Interfaces_Get(
+    unsigned int * const NofPEs_p,
+    unsigned int * const NofRings_p,
+    unsigned int * const NofLA_p,
+    unsigned int * const NofIN_p)
+{
+    if (NofPEs_p)
+        *NofPEs_p = Global97_NofPEs;
+    if (NofRings_p)
+        *NofRings_p = Global97_NofRings;
+    if (NofLA_p)
+        *NofLA_p = Global97_NofLA;
+    if (NofIN_p)
+        *NofIN_p = Global97_NofIN;
+}
+
+/*----------------------------------------------------------------------------
+ * EIP97_DFEDSE_Offset_Get
+ */
+unsigned int
+EIP97_DFEDSE_Offset_Get(void)
+{
+    return Global97_DFEDSEOffset;
+}
+
+
+unsigned int
+EIP97_SupportedFuncs_Get(void)
+{
+    return Global97_SupportedFuncs;
+}
+
+
+/* end of file eip97_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c
new file mode 100644
index 0000000..eb41088
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c
@@ -0,0 +1,120 @@
+/* eip97_global_prng.c
+ *
+ * EIP-97 GLobal Control Driver Library
+ * PRNG Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/*                                                                            */
+/*   Module        : ddk197                                                   */
+/*   Version       : 5.6.1                                                    */
+/*   Configuration : DDK-197-GPL                                              */
+/*                                                                            */
+/*   Date          : 2022-Dec-16                                              */
+/*                                                                            */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.           */
+/*                                                                            */
+/* This program is free software: you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, either version 2 of the License, or          */
+/* any later version.                                                         */
+/*                                                                            */
+/* This program is distributed in the hope that it will be useful,            */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               */
+/* GNU General Public License for more details.                               */
+/*                                                                            */
+/* You should have received a copy of the GNU General Public License          */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>.       */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_prng.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Device API
+#include "device_types.h"              // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip96_level0.h"              // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h"          // State machine
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_PRNG_Reseed
+ */
+EIP97_Global_Error_t
+EIP97_Global_PRNG_Reseed(
+        EIP97_Global_IOArea_t * const IOArea_p,
+        const unsigned int PE_Number,
+        const EIP96_PRNG_Reseed_t * const ReseedData_p)
+{
+    Device_Handle_t Device;
+    volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+    EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+    if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+        return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+    Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+    {
+        EIP97_Global_Error_t rv;
+
+        // Remain in the current state
+        rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+                                    (EIP97_Global_State_t)TrueIOArea_p->State);
+        if(rv != EIP97_GLOBAL_NO_ERROR)
+            return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+    }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+    EIP96_PRNG_CTRL_WR(Device,
+                       PE_Number, // EIP-96 PE number
+                       false,     // Disable PRNG
+                       false);    // Set PRNG Manual mode
+
+    // Write new seed data
+    EIP96_PRNG_SEED_L_WR(Device, PE_Number, ReseedData_p->SeedLo);
+    EIP96_PRNG_SEED_H_WR(Device, PE_Number, ReseedData_p->SeedHi);
+
+    // Write new key data
+    EIP96_PRNG_KEY_0_L_WR(Device, PE_Number, ReseedData_p->Key0Lo);
+    EIP96_PRNG_KEY_0_H_WR(Device, PE_Number, ReseedData_p->Key0Hi);
+    EIP96_PRNG_KEY_1_L_WR(Device, PE_Number, ReseedData_p->Key1Lo);
+    EIP96_PRNG_KEY_1_H_WR(Device, PE_Number, ReseedData_p->Key1Hi);
+
+    // Write new LFSR data
+    EIP96_PRNG_LFSR_L_WR(Device, PE_Number, ReseedData_p->LFSRLo);
+    EIP96_PRNG_LFSR_H_WR(Device, PE_Number, ReseedData_p->LFSRHi);
+
+    EIP96_PRNG_CTRL_WR(Device,
+                       PE_Number, // EIP-96 PE number
+                       true,      // Enable PRNG
+                       true);     // Set PRNG Auto mode
+
+    return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_prng.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c
new file mode 100644
index 0000000..a9a3498
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c
@@ -0,0 +1,633 @@
+/* iotoken.c
+ *
+ * IOToken API implementation for the EIP-197 Server with ICE only
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Extended IOToken API
+#include "iotoken_ext.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_iotoken.h"              // IOTOKEN_STRICT_ARGS
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"             // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Firmware packet flow codes
+#include "firmware_eip207_api_cmd.h"
+
+// ZEROINIT
+#include "clib.h"
+
+#include "log.h"
+
+// Packet buffer access
+#include "adapter_pec_pktbuf.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define IOTOKEN_ARGUMENT_ERROR      -1
+#define IOTOKEN_INTERNAL_ERROR      -2
+
+#ifdef IOTOKEN_STRICT_ARGS
+#define IOTOKEN_CHECK_POINTER(_p) \
+    if (NULL == (_p)) \
+        return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_INRANGE(_i, _min, _max) \
+    if ((_i) < (_min) || (_i) > (_max)) \
+        return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_ATLEAST(_i, _min) \
+    if ((_i) < (_min)) \
+        return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_ATMOST(_i, _max) \
+    if ((_i) > (_max)) \
+        return IOTOKEN_ARGUMENT_ERROR;
+#else
+/* IOTOKEN_STRICT_ARGS undefined */
+#define IOTOKEN_CHECK_POINTER(_p)
+#define IOTOKEN_CHECK_INT_INRANGE(_i, _min, _max)
+#define IOTOKEN_CHECK_INT_ATLEAST(_i, _min)
+#define IOTOKEN_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of IOTOKEN_STRICT_ARGS */
+
+// Input Token words offsets
+#define IOTOKEN_HDR_IN_WORD_OFFS           0
+#define IOTOKEN_APP_ID_IN_WORD_OFFS        1
+#define IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS    2
+#define IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS    3
+#define IOTOKEN_HW_SERVICES_IN_WORD_OFFS   4
+#define IOTOKEN_NH_OFFSET_IN_WORD_OFFS     5
+#define IOTOKEN_BP_DATA_IN_WORD_OFFS       6
+
+// Output Token words offsets
+#define IOTOKEN_HDR_OUT_WORD_OFFS          0
+#define IOTOKEN_BP_LEN_OUT_WORD_OFFS       1
+#define IOTOKEN_APP_ID_OUT_WORD_OFFS       2
+#define IOTOKEN_PAD_NH_OUT_WORD_OFFS       3
+#define IOTOKEN_SA_ADDR_LO_OUT_WORD_OFFS   4
+#define IOTOKEN_SA_ADDR_HI_OUT_WORD_OFFS   5
+#define IOTOKEN_NPH_CTX_OUT_WORD_OFFS      6
+#define IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS 7
+#define IOTOKEN_BP_DATA_OUT_WORD_OFFS      8
+
+#define IOTOKEN_MARK                       0xEC00
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_InWordCount_Get
+ */
+unsigned int
+IOToken_InWordCount_Get(void)
+{
+    return IOTOKEN_IN_WORD_COUNT - 4 + IOTOKEN_BYPASS_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_OutWordCount_Get
+ */
+unsigned int
+IOToken_OutWordCount_Get(void)
+{
+    return IOTOKEN_OUT_WORD_COUNT - 4 + IOTOKEN_BYPASS_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Create
+ */
+int
+IOToken_Create(
+        const IOToken_Input_Dscr_t * const Dscr_p,
+        uint32_t * Data_p)
+{
+    IOToken_Input_Dscr_Ext_t * DscrExt_p;
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+    unsigned int bypass_gap = 0;
+#endif
+    unsigned int i;
+
+    IOTOKEN_CHECK_POINTER(Dscr_p);
+    IOTOKEN_CHECK_POINTER(Dscr_p->Ext_p);
+    IOTOKEN_CHECK_POINTER(Data_p);
+
+    DscrExt_p = (IOToken_Input_Dscr_Ext_t *)Dscr_p->Ext_p;
+
+    // Input Token word: EIP-96 Token Header Word
+    {
+        i = IOTOKEN_HDR_IN_WORD_OFFS;
+
+        // Set initialization value in the Token Header Word excluding packet
+        // size field
+        Data_p[i] = Dscr_p->TknHdrWordInit & ~MASK_16_BITS;
+
+        // Input packet size
+        Data_p[i] |= Dscr_p->InPacket_ByteCount & MASK_16_BITS;
+
+        if (DscrExt_p->HW_Services == IOTOKEN_CMD_PKT_LAC)
+        {
+            // Options, ARC4 pre-fetch
+            if (DscrExt_p->fARC4Prefetch)
+                Data_p[i] |= BIT_16;
+
+            Data_p[i] |= BIT_17; // Set token header format to EIP-(1)97
+
+            Data_p[i] |= BIT_18; // Only 64-bit Context (SA) pointer is supported
+
+            // Enable Context Reuse auto detect if no new SA
+            if (Dscr_p->Options.fReuseSA)
+                Data_p[i] |= BIT_21;
+        }
+        // Mask size for inbound ESP
+        if (DscrExt_p->SequenceMaskBitCount != 0)
+        {
+            switch(DscrExt_p->SequenceMaskBitCount)
+            {
+            case 64:
+                Data_p[i] |= 0x00200000;
+                break;
+            case 128:
+                Data_p[i] |= 0x00400000;
+                break;
+            case 256:
+                Data_p[i] |= 0x00600000;
+                break;
+            case 512:
+                Data_p[i] |= 0x00800000;
+                break;
+            }
+        }
+        // Extended options for LIP
+        if (DscrExt_p->fEncLastDest)
+            Data_p[i] |= BIT_25;
+        // Extended options for in-line DTLS packet flow
+        {
+            if (DscrExt_p->Options.fCAPWAP)
+                Data_p[i] |= BIT_26;
+
+            if (DscrExt_p->Options.fInbound)
+                Data_p[i] |= BIT_27;
+
+            Data_p[i] |= DscrExt_p->Options.ContentType << 28;
+        }
+
+        Data_p[i] |= IOTOKEN_FLOW_TYPE << 30; // Implemented flow type
+    }
+
+    // Input Token word: Application ID
+    {
+        i = IOTOKEN_APP_ID_IN_WORD_OFFS;
+        Data_p[i] = (Dscr_p->AppID & MASK_7_BITS) << 9;
+        Data_p[i] |= (DscrExt_p->AAD_ByteCount & MASK_8_BITS);
+        if (DscrExt_p->fInline)
+            Data_p[i] |= (32 + IOTOKEN_BYPASS_WORD_COUNT*4) << 16;
+    }
+
+    // Input Token word: Context (SA) low 32 bits physical address
+    {
+        i = IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS;
+        Data_p[i] = Dscr_p->SA_PhysAddr.Lo;
+    }
+
+    // Input Token word: Context (SA) high 32 bits physical address
+    {
+        i = IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS;
+        //if (DscrExt_p->Options.f64bitSA) // Only 64-bit SA address supported
+            Data_p[i] = Dscr_p->SA_PhysAddr.Hi;
+    }
+
+    // Input Token word: HW services, e,g, packet flow selection
+    {
+        i = IOTOKEN_HW_SERVICES_IN_WORD_OFFS;
+        Data_p[i] = ((DscrExt_p->HW_Services & MASK_8_BITS) << 24) |
+            (DscrExt_p->UserDef & MASK_16_BITS);
+        if (DscrExt_p->fStripPadding != IOTOKEN_PADDING_DEFAULT_ON)
+            Data_p[i] |= BIT_22;
+        if (DscrExt_p->fAllowPadding != IOTOKEN_PADDING_DEFAULT_ON)
+            Data_p[i] |= BIT_23;
+    }
+
+    // Input Token word: Offset and Next Header
+    {
+        i = IOTOKEN_NH_OFFSET_IN_WORD_OFFS;
+        Data_p[i] = (DscrExt_p->Offset_ByteCount & MASK_8_BITS) << 8;
+        Data_p[i] |= (DscrExt_p->NextHeader & MASK_8_BITS) << 16;
+        if (DscrExt_p->fFL)
+            Data_p[i] |= BIT_24;
+        if (DscrExt_p->fIPv4Chksum)
+            Data_p[i] |= BIT_25;
+        if (DscrExt_p->fL4Chksum)
+            Data_p[i] |= BIT_26;
+        if (DscrExt_p->fParseEther)
+            Data_p[i] |= BIT_27;
+        if (DscrExt_p->fKeepOuter)
+            Data_p[i] |= BIT_28;
+
+    }
+
+    if (DscrExt_p->fInline)
+    {
+        Data_p[IOTOKEN_BP_DATA_IN_WORD_OFFS]=0;
+        Data_p[IOTOKEN_BP_DATA_IN_WORD_OFFS+1]=0;
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+        bypass_gap = 2;
+#endif
+    }
+
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+    // Input Token word: Bypass Data
+    {
+        unsigned int j;
+
+        if (DscrExt_p->BypassData_p)
+        {
+            for (j = 0; j < IOTOKEN_BYPASS_WORD_COUNT; j++)
+                Data_p[j+IOTOKEN_BP_DATA_IN_WORD_OFFS + bypass_gap] = DscrExt_p->BypassData_p[j];
+        }
+        else
+        {
+            for (j = 0; j < IOTOKEN_BYPASS_WORD_COUNT; j++)
+                Data_p[j+IOTOKEN_BP_DATA_IN_WORD_OFFS + bypass_gap] = 0xf0f0f0f0;
+        }
+        i += bypass_gap + j;
+    }
+#endif
+
+    if (i  >= IOTOKEN_IN_WORD_COUNT_IL)
+        return IOTOKEN_INTERNAL_ERROR;
+    else
+        return i+1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Fixup
+ */
+int
+IOToken_Fixup(
+        uint32_t * const Data_p,
+        const DMABuf_Handle_t PacketHandle)
+{
+    uint32_t AppendFlags;
+    if (Data_p == NULL)
+        return 0;
+
+    AppendFlags = Data_p[IOTOKEN_BP_LEN_OUT_WORD_OFFS] & (BIT_31|BIT_30|BIT_29);
+    if (AppendFlags != 0)
+    {
+        uint8_t AppendData[12];
+        uint8_t *Append_p;
+        unsigned int Offset;
+        unsigned int PrevNH_Offset;
+        unsigned int UpdateOffset;
+        unsigned int AppendLen = 0;
+        if ((AppendFlags & BIT_31) != 0)
+            AppendLen+=4;
+        if ((AppendFlags & BIT_30) != 0)
+            AppendLen+=4;
+        if ((AppendFlags & BIT_29) != 0)
+            AppendLen+=4;
+        UpdateOffset = Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & MASK_17_BITS;
+        UpdateOffset = 4*((UpdateOffset + 3)/4); // Align to word boundary.
+        Offset = Data_p[IOTOKEN_PAD_NH_OUT_WORD_OFFS] >> 16 & MASK_8_BITS;
+        // Get first byte of header
+        Append_p = Adapter_PEC_PktData_Get(PacketHandle, AppendData, UpdateOffset, AppendLen);
+        if (AppendFlags == (BIT_31|BIT_30))
+        { // IPv6 header update, NH plus length
+            PrevNH_Offset = Data_p[IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS] & MASK_16_BITS;
+            Adapter_PEC_PktByte_Put(PacketHandle, PrevNH_Offset, Append_p[4]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 4, Append_p[0]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 5, Append_p[1]);
+            LOG_INFO("IOToken_Fixup: IPv6 inbound transport\n");
+        }
+        else if (AppendFlags == BIT_29)
+        { // IPv4 checksum only update
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 10, Append_p[0]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 11, Append_p[1]);
+            LOG_INFO("IOToken_Fixup: IPv4 inbound tunnel\n");
+        }
+        else if (AppendFlags == (BIT_31|BIT_30|BIT_29))
+        { // IPv4 header update, proto + length + checksum.
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 2, Append_p[0]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 3, Append_p[1]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 9, Append_p[5]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 10, Append_p[8]);
+            Adapter_PEC_PktByte_Put(PacketHandle, Offset + 11, Append_p[9]);
+            LOG_INFO("IOToken_Fixup: IPv4 inbound transport\n");
+        }
+        else
+        {
+            LOG_CRIT("IOToken_Fixup: Unexpected flags combination 0x%08x\n",
+                     AppendFlags);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAAddr_Update
+ */
+int
+IOToken_SAAddr_Update(
+        const IOToken_PhysAddr_t * const SA_PhysAddr_p,
+        uint32_t * InTokenData_p)
+{
+    IOTOKEN_CHECK_POINTER(SA_PhysAddr_p);
+    IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+    // Input Token word: Context (SA) low 32 bits physical address
+    InTokenData_p[IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS] = SA_PhysAddr_p->Lo;
+
+    // Input Token word: Context (SA) high 32 bits physical address
+    InTokenData_p[IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS] = SA_PhysAddr_p->Hi;
+
+    return 2; // updated 32-bit token words
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAReuse_Update
+ */
+int
+IOToken_SAReuse_Update(
+        const bool fReuseSA,
+        uint32_t * InTokenData_p)
+{
+    IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+    // Enable Context Reuse auto detect if no new SA
+    if (fReuseSA)
+        InTokenData_p[IOTOKEN_HDR_IN_WORD_OFFS] |= BIT_21;
+    else
+        InTokenData_p[IOTOKEN_HDR_IN_WORD_OFFS] &= ~BIT_21;
+
+    return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Set
+ */
+int
+IOToken_Mark_Set(
+        uint32_t * InTokenData_p)
+{
+    IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+    InTokenData_p[IOTOKEN_APP_ID_IN_WORD_OFFS] &= ~(MASK_7_BITS << 9);
+    InTokenData_p[IOTOKEN_APP_ID_IN_WORD_OFFS] |= IOTOKEN_MARK;
+
+    return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Offset_Get
+ */
+int
+IOToken_OutMarkOffset_Get(void)
+{
+    return IOTOKEN_APP_ID_OUT_WORD_OFFS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Check
+ */
+int
+IOToken_Mark_Check(
+        uint32_t * OutTokenData_p)
+{
+    uint32_t Mark;
+
+    IOTOKEN_CHECK_POINTER(OutTokenData_p);
+
+    Mark = OutTokenData_p[IOTOKEN_APP_ID_OUT_WORD_OFFS] & IOTOKEN_MARK;
+
+    if (Mark == IOTOKEN_MARK)
+        return 0;
+    else
+        return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Parse
+ */
+int
+IOToken_Parse(
+        const uint32_t * Data_p,
+        IOToken_Output_Dscr_t * const Dscr_p)
+{
+    unsigned int i, j = 0;
+    IOToken_Output_Dscr_Ext_t * Ext_p;
+
+    IOTOKEN_CHECK_POINTER(Data_p);
+    IOTOKEN_CHECK_POINTER(Dscr_p);
+
+    Ext_p = (IOToken_Output_Dscr_Ext_t *)Dscr_p->Ext_p;
+
+    // Output Token word: EIP-96 Output Token Header Word
+    {
+        i = IOTOKEN_HDR_OUT_WORD_OFFS;
+        Dscr_p->OutPacket_ByteCount = Data_p[i]       & MASK_17_BITS;
+        Dscr_p->ErrorCode           = Data_p[i] >> 17 & MASK_15_BITS;
+    }
+
+    // Output Token word: EIP-96 Output Token Bypass Data Length Word
+    {
+        i = IOTOKEN_BP_LEN_OUT_WORD_OFFS;
+        Dscr_p->BypassData_ByteCount =  Data_p[i] & MASK_4_BITS;
+        Dscr_p->fHashAppended        = (Data_p[i] & BIT_21) != 0;
+
+        Dscr_p->Hash_ByteCount       = Data_p[i] >> 22 & MASK_6_BITS;
+
+        Dscr_p->fBytesAppended       = (Data_p[i] & BIT_28) != 0;
+        Dscr_p->fChecksumAppended    = (Data_p[i] & BIT_29) != 0;
+        Dscr_p->fNextHeaderAppended  = (Data_p[i] & BIT_30) != 0;
+        Dscr_p->fLengthAppended      = (Data_p[i] & BIT_31) != 0;
+    }
+
+    // Output Token word: EIP-96 Output Token Application ID Word
+    {
+        i = IOTOKEN_APP_ID_OUT_WORD_OFFS;
+        Dscr_p->AppID = Data_p[i] >> 9 & MASK_7_BITS;
+    }
+
+    // Output Token word: Pad Length and Next Header
+    {
+        i = IOTOKEN_PAD_NH_OUT_WORD_OFFS;
+        Dscr_p->NextHeader    = Data_p[i]      & MASK_8_BITS;
+        Dscr_p->Pad_ByteCount = Data_p[i] >> 8 & MASK_8_BITS;
+    }
+
+    // Parse Output Token descriptor extension if requested
+    if (Ext_p)
+    {
+        // Output Token word: ToS/TC, DF, Firmware errors
+        {
+            j = IOTOKEN_BP_LEN_OUT_WORD_OFFS;
+            Ext_p->TOS_TC    = Data_p[j] >> 5  & MASK_8_BITS;
+
+            Ext_p->fDF       = (Data_p[j] & BIT_13) != 0;
+
+            Ext_p->CfyErrors = Data_p[j] >> 16 & MASK_5_BITS;
+        }
+
+#ifdef IOTOKEN_EXTENDED_ERRORS_ENABLE
+        if ((Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & BIT_31) != 0)
+        {
+            Ext_p->ExtErrors = (Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] >> 17) & MASK_8_BITS;
+        }
+        else
+#endif
+        {
+            Ext_p->ExtErrors = 0;
+        }
+
+        // Output Token word: IP Length Delta and Offset
+        {
+            j = IOTOKEN_PAD_NH_OUT_WORD_OFFS;
+            Ext_p->Offset_ByteCount  = Data_p[j] >> 16 & MASK_8_BITS;
+            Ext_p->IPDelta_ByteCount = Data_p[j] >> 24 & MASK_8_BITS;
+        }
+
+        // Output Token word: SA physical address low/high words
+        {
+            j = IOTOKEN_SA_ADDR_LO_OUT_WORD_OFFS;
+            Ext_p->SA_PhysAddr.Lo = Data_p[j];
+
+            j = IOTOKEN_SA_ADDR_HI_OUT_WORD_OFFS;
+            Ext_p->SA_PhysAddr.Hi = Data_p[j];
+        }
+
+        // Output Token word: Application header processing context
+        {
+            j = IOTOKEN_NPH_CTX_OUT_WORD_OFFS;
+            Ext_p->NPH_Context = Data_p[j];
+        }
+
+        // Output Token word: Previous Next Header Offset
+        {
+            j = IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS;
+            Ext_p->NextHeaderOffset = Data_p[j] & MASK_16_BITS;
+            Ext_p->fInIPv6 = ((Data_p[j] & BIT_16) != 0);
+            Ext_p->fFromEther = ((Data_p[j] & BIT_17) != 0);
+            Ext_p->fOutIPv6 = ((Data_p[j] & BIT_22) != 0);
+            Ext_p->fInbTunnel = ((Data_p[j] & BIT_23) != 0);
+        }
+
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+        // Output Token word: Bypass Data
+        {
+            unsigned int k = 0;
+            if (Ext_p->BypassData_p)
+            {
+                for (k = 0; k < IOTOKEN_BYPASS_WORD_COUNT; k++)
+                    Ext_p->BypassData_p[k] =
+                        Data_p[k+IOTOKEN_BP_DATA_OUT_WORD_OFFS];
+            }
+            j += k;
+        }
+#endif
+    }
+
+    // Output Token word: Reserved word not used
+    // i = IOTOKEN_RSVD_OUT_WORD_OFFS;
+
+    return MAX(i, j);
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_PacketLegth_Get
+ */
+int
+IOToken_PacketLegth_Get(
+        const uint32_t * Data_p,
+        unsigned int * Pkt_ByteCount_p)
+{
+    IOTOKEN_CHECK_POINTER(Data_p);
+    IOTOKEN_CHECK_POINTER(Pkt_ByteCount_p);
+
+    *Pkt_ByteCount_p = Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & MASK_17_BITS;
+
+    return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_BypassLegth_Get
+ */
+int
+IOToken_BypassLegth_Get(
+        const uint32_t * Data_p,
+        unsigned int * BD_ByteCount_p)
+{
+    IOTOKEN_CHECK_POINTER(Data_p);
+    IOTOKEN_CHECK_POINTER(BD_ByteCount_p);
+
+    *BD_ByteCount_p = Data_p[IOTOKEN_BP_LEN_OUT_WORD_OFFS] & MASK_4_BITS;
+
+    return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_ErrorCode_Get
+ */
+int
+IOToken_ErrorCode_Get(
+        const uint32_t * Data_p,
+        unsigned int * ErrorCode_p)
+{
+    IOTOKEN_CHECK_POINTER(Data_p);
+    IOTOKEN_CHECK_POINTER(ErrorCode_p);
+
+    *ErrorCode_p = (Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] >> 17) & MASK_15_BITS;
+#ifdef IOTOKEN_EXTENDED_ERRORS_ENABLE
+    if ((Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & BIT_31) != 0)
+    {
+        *ErrorCode_p &= ~0x40ff; // Remove the detailed error code and related bits.
+    }
+#endif
+
+    return 1;
+}
+
+
+/* end of file iotoken.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c
new file mode 100644
index 0000000..86b0727
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c
@@ -0,0 +1,459 @@
+/* list.c
+ *
+ * This Module implements the List API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// List API
+#include "list.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_list.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    // List head
+    List_Element_t * Head_p;
+
+    // List tail
+    List_Element_t * Tail_p;
+
+    // Number of elements in the list
+    unsigned int ElementCount;
+
+} List_t;
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+// Statically allocated list instances. This will be deprecated in future.
+static List_t List [LIST_MAX_NOF_INSTANCES];
+
+
+/*----------------------------------------------------------------------------
+ * List_Init
+ *
+ */
+List_Status_t
+List_Init(
+        const unsigned int ListID,
+        void * const ListInstance_p)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Initialize the list instance
+    {
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+        List_p->ElementCount    = 0;
+        List_p->Head_p          = NULL;
+        List_p->Tail_p          = NULL;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_Uninit
+ *
+ */
+List_Status_t
+List_Uninit(
+        const unsigned int ListID,
+        void * const ListInstance_p)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Un-initialize the list instance
+    {
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+        List_p->ElementCount    = 0;
+        List_p->Head_p          = NULL;
+        List_p->Tail_p          = NULL;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_AddToHead
+ *
+ */
+List_Status_t
+List_AddToHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t * const Element_p)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Element_p == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Add the element at the list head
+    {
+        List_Element_t * TempElement_p;
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+        TempElement_p           = List_p->Head_p;
+        List_p->Head_p          = Element_p;
+
+        // Previous element in the list, this is a head
+        Element_p->Internal[0]  = NULL;
+
+        // Next element in the list
+        Element_p->Internal[1]  = TempElement_p;
+
+        // Check if this is the first element
+        if (List_p->ElementCount == 0)
+            List_p->Tail_p = List_p->Head_p;
+        else
+            // Link the old head to the new head
+            TempElement_p->Internal[0] = Element_p;
+
+        List_p->ElementCount++;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveFromTail
+ *
+ */
+List_Status_t
+List_RemoveFromTail(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t ** const Element_pp)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Element_pp == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+#endif // LIST_STRICT_ARGS
+
+    // Remove the element from the list tail
+    {
+        List_Element_t * TempElement_p;
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+        if (List_p->ElementCount == 0)
+            return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+        // Get the previous for the tail element in the list
+        TempElement_p = (List_Element_t*)List_p->Tail_p->Internal[0];
+
+        List_p->Tail_p->Internal[0] = NULL;
+        List_p->Tail_p->Internal[1] = NULL;
+        *Element_pp                 = List_p->Tail_p;
+
+        // Set the new tail
+        List_p->Tail_p              = TempElement_p;
+
+        // Check if this is the last element
+        if (List_p->ElementCount == 1)
+            List_p->Head_p = NULL;
+        else
+            // New tail must have no next element
+            List_p->Tail_p->Internal[1] = NULL;
+
+        List_p->ElementCount--;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveAnywhere
+ */
+List_Status_t
+List_RemoveAnywhere(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t * const Element_p)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Element_p == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Remove the element from the list tail
+    {
+        List_Element_t * PrevElement_p, * NextElement_p;
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+        if (List_p->ElementCount == 0)
+            return LIST_ERROR_BAD_ARGUMENT;
+
+        // Check element belongs to this list
+        {
+            unsigned int i;
+            List_Element_t * TempElement_p = List_p->Head_p;
+
+            for (i = 0; i < List_p->ElementCount; i++)
+            {
+                List_Element_t * p;
+
+                if (TempElement_p == Element_p)
+                    break; // Found
+
+                p = TempElement_p->Internal[1];
+                if (p)
+                    TempElement_p = p; // not end of list yet
+                else
+                    return LIST_ERROR_BAD_ARGUMENT; // Not found
+            }
+
+            if (TempElement_p != Element_p)
+                return LIST_ERROR_BAD_ARGUMENT; // Not found
+        }
+#endif // LIST_STRICT_ARGS
+
+        PrevElement_p = Element_p->Internal[0];
+        NextElement_p = Element_p->Internal[1];
+
+        Element_p->Internal[0] = NULL;
+        Element_p->Internal[1] = NULL;
+
+        if (PrevElement_p)
+            PrevElement_p->Internal[1] = NextElement_p;
+        else
+            List_p->Head_p = NextElement_p;
+
+        if (NextElement_p)
+            NextElement_p->Internal[0] = PrevElement_p;
+        else
+            List_p->Tail_p = PrevElement_p;
+
+        List_p->ElementCount--;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_GetListElementCount
+ *
+ */
+List_Status_t
+List_GetListElementCount(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        unsigned int * const Count_p)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Count_p == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    {
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+        *Count_p = List_p->ElementCount;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+#ifdef LIST_FULL_API
+/*----------------------------------------------------------------------------
+ * List_RemoveFromHead
+ *
+ */
+List_Status_t
+List_RemoveFromHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        List_Element_t ** const Element_pp)
+{
+    List_t * List_p;
+
+    if (ListInstance_p)
+        List_p = (List_t*)ListInstance_p;
+    else
+        List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Element_pp == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (List_p->ElementCount == 0)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Remove the element from the list head
+    {
+        List_Element_t * TempElement_p;
+
+        // Get the next for the head element in the list
+        TempElement_p = (List_Element_t*)List_p->Head_p->Internal[1];
+
+        List_p->Head_p->Internal[0] = NULL;
+        List_p->Head_p->Internal[1] = NULL;
+        *Element_pp                 = List_p->Head_p;
+
+        List_p->Head_p              = TempElement_p;
+
+        // Check if this is the last element
+        if (List_p->ElementCount == 1)
+            List_p->Tail_p = NULL;
+        else
+            List_p->Head_p->Internal[0] = NULL;
+
+        List_p->ElementCount--;
+    }
+
+    return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_GetHead
+ */
+List_Status_t
+List_GetHead(
+        const unsigned int ListID,
+        void * const ListInstance_p,
+        const List_Element_t ** const Element_pp)
+{
+#ifdef LIST_STRICT_ARGS
+    if (ListID >= LIST_MAX_NOF_INSTANCES)
+        return LIST_ERROR_BAD_ARGUMENT;
+
+    if (Element_pp == NULL)
+        return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+    // Get the list head
+    {
+        List_t * List_p;
+
+        if (ListInstance_p)
+            List_p = (List_t*)ListInstance_p;
+        else
+            List_p = &List[ListID];
+
+        *Element_pp = List_p->Head_p;
+    }
+
+    return LIST_STATUS_OK;
+}
+#endif // LIST_FULL_API
+
+
+/*----------------------------------------------------------------------------
+ * List_GetInstanceByteCount
+ *
+ * Gets the memory size of the list instance (in bytes) excluding the list
+ * elements memory size. This list memory size can be used to allocate a list
+ * instance and pass a pointer to it subsequently to the List_*() functions.
+ *
+ * This function is re-entrant and can be called any time.
+ *
+ * Return Values
+ *     Size of the list administration memory in bytes.
+ */
+unsigned int
+List_GetInstanceByteCount(void)
+{
+    return sizeof(List_t);
+}
+
+
+/* end of file list.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c
new file mode 100644
index 0000000..84473f9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c
@@ -0,0 +1,128 @@
+/* log.c
+ *
+ * Log implementation for specific environment
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#define LOG_SEVERITY_MAX  LOG_SEVERITY_NO_OUTPUT
+
+// Logging API
+#include "log.h"            // the API to implement
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump
+ *
+ * This function logs Hex Dump of a Buffer
+ *
+ * szPrefix
+ *     Prefix to be printed on every row.
+ *
+ * PrintOffset
+ *     Offset value that is printed at the start of every row. Can be used
+ *     when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ *     Pointer to the start of the array of bytes to hex dump.
+ *
+ * ByteCount
+ *     Number of bytes to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ *     None.
+ */
+void
+Log_HexDump(
+        const char * szPrefix_p,
+        const unsigned int PrintOffset,
+        const uint8_t * Buffer_p,
+        const unsigned int ByteCount)
+{
+    unsigned int i;
+
+    for(i = 0; i < ByteCount; i += 16)
+    {
+        unsigned int j, Limit;
+
+        // if we do not have enough data for a full line
+        if (i + 16 > ByteCount)
+            Limit = ByteCount - i;
+        else
+            Limit = 16;
+
+        Log_FormattedMessage("%s %08d:", szPrefix_p, PrintOffset + i);
+
+        for (j = 0; j < Limit; j++)
+            Log_FormattedMessage(" %02X", Buffer_p[i+j]);
+
+        Log_FormattedMessage("\n");
+    } // for
+}
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump32
+ *
+ * This function logs Hex Dump of an array of 32-bit words
+ *
+ * szPrefix
+ *     Prefix to be printed on every row.
+ *
+ * PrintOffset
+ *     Offset value that is printed at the start of every row. Can be used
+ *     when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ *     Pointer to the start of the array of 32-bit words to hex dump.
+ *
+ * Word32Count
+ *     Number of 32-bit words to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ *     None.
+ */
+void
+Log_HexDump32(
+        const char * szPrefix_p,
+        const unsigned int PrintOffset,
+        const uint32_t * Buffer_p,
+        const unsigned int Word32Count)
+{
+    unsigned int i;
+
+    for(i = 0; i < Word32Count; i += 4)
+    {
+        unsigned int j, Limit;
+
+        // if we do not have enough data for a full line
+        if (i + 4 > Word32Count)
+            Limit = Word32Count - i;
+        else
+            Limit = 4;
+
+        Log_FormattedMessage("%s %08d:", szPrefix_p, PrintOffset + i*4);
+
+        for (j = 0; j < Limit; j++)
+            Log_FormattedMessage(" %08X", Buffer_p[i+j]);
+
+        Log_FormattedMessage("\n");
+    } // for
+}
+
+/* end of file log.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c
new file mode 100644
index 0000000..fd04cd3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c
@@ -0,0 +1,484 @@
+/* ringhelper.c
+ *
+ * Ring Helper Library implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#include "c_ringhelper.h"  // configuration options
+
+#include "basic_defs.h"     // bool, MIN
+#include "ringhelper.h"     // API to implement
+#include "clib.h"           // memset
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Init
+ *
+ * This routine must be called once to initialize the administration block
+ * related to a ring.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Init(
+        volatile RingHelper_t * const Ring_p,
+        volatile const RingHelper_CallbackInterface_t * const CallbackIF_p,
+        const bool fSeparateRings,
+        const unsigned int CommandRing_MaxDescriptors,
+        const unsigned int ResultRing_MaxDescriptors)
+{
+#ifdef RINGHELPER_STRICT_ARGS
+    if (Ring_p == NULL ||
+        CallbackIF_p == NULL ||
+        CommandRing_MaxDescriptors < 1)
+    {
+        // invalid argument
+        return -1;
+    }
+
+    if (fSeparateRings)
+    {
+#ifdef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+        // not supported
+        return -1;
+#else
+        if (ResultRing_MaxDescriptors < 1)
+        {
+            // invalid arguments
+            return -1;
+        }
+#endif
+    }
+
+    if (CallbackIF_p->ReadFunc_p == NULL ||
+        CallbackIF_p->WriteFunc_p == NULL)
+    {
+        return -1;
+    }
+
+#ifndef RINGHELPER_REMOVE_STATUSFUNC
+    if (CallbackIF_p->StatusFunc_p == NULL)
+    {
+        return -1;
+    }
+#endif
+
+#endif /* RINGHELPER_STRICT_ARGS */
+
+    Ring_p->CB = *CallbackIF_p;
+    Ring_p->fSupportsDeviceReadPos = true;      // initial assumption
+    Ring_p->IN_Size = CommandRing_MaxDescriptors;
+    Ring_p->IN_Tail = 0;
+    Ring_p->OUT_Head = 0;
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+    if (fSeparateRings)
+    {
+        // separate rings
+        Ring_p->fSeparate = true;
+        Ring_p->OUT_Size = ResultRing_MaxDescriptors;
+    }
+    else
+#endif /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+    {
+        // combined rings
+        Ring_p->fSeparate = false;
+        Ring_p->OUT_Size = CommandRing_MaxDescriptors;
+    }
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Put
+ *
+ * This function tries to add a number of descriptors to the command ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Put(
+        volatile RingHelper_t * const Ring_p,
+        const void * Descriptors_p,
+        const int DescriptorCount)
+{
+    int A, N, W1, W2;
+
+#ifdef RINGHELPER_STRICT_ARGS
+    if (Ring_p == NULL ||
+        Descriptors_p == NULL ||
+        DescriptorCount < 0)
+    {
+        return -1;
+    }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+    if (DescriptorCount == 0)
+        return 0;
+
+    W2 = 0;
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+    // out of the descriptors provided, calculate the maximum number of
+    // descriptors that can be written sequentially before the ring is full.
+    if (Ring_p->fSeparate)
+    {
+        // separate rings
+
+        // ask how far the device has processed the ring
+        // we do this on every call and do not cache the result
+        int DeviceReadHead = -1;    // not supported
+
+#ifndef RINGHELPER_REMOVE_STATUSFUNC
+        if (Ring_p->fSupportsDeviceReadPos)
+        {
+            int res;
+
+            res = Ring_p->CB.StatusFunc_p(
+                                 Ring_p->CB.CallbackParam1_p,
+                                 Ring_p->CB.CallbackParam2,
+                                 &DeviceReadHead);
+
+            if (res < 0)
+                return res;     // ## RETURN ##
+
+            // suppress these calls if the device does not support it
+            if (DeviceReadHead < 0)
+                Ring_p->fSupportsDeviceReadPos = false;
+        }
+#endif /* !RINGHELPER_REMOVE_STATUSFUNC */
+
+        if (DeviceReadHead < 0)
+        {
+            // device does not expose its read position
+            // this means we cannot calculate how much space is available
+            // the WriteFunc will have to check, descriptor by descriptor
+            A = Ring_p->IN_Size;
+
+            // note: under this condition we rely on the implementation of
+            // the callback interface to handle ring-full condition and not
+            // overwrite existing descriptors. Because of this, we can
+            // fill the ring to the limit and do not have to keep 1 free
+            // position as done below.
+        }
+        else
+        {
+            unsigned int Device_IN_Head = (unsigned int)DeviceReadHead;
+
+            // based on the device read position we can calculate
+            // how many positions in the ring are free
+            if (Ring_p->IN_Tail < Device_IN_Head)
+            {
+                // we have wrapped around
+                // available space is between the two
+                A = Device_IN_Head - Ring_p->IN_Tail;
+            }
+            else
+            {
+                // used positions are between the two pointers
+                // rest is free
+                A = Ring_p->IN_Size - (Ring_p->IN_Tail - Device_IN_Head);
+            }
+
+            // avoid filling the entire ring
+            // so we can differentiate full from empty
+            if (A != 0)
+                A--;
+        }
+    }
+    else
+#endif /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+    {
+        // combined rings
+
+        // Critical: we have to be careful not to read the OUT_Head more
+        //           than one, since it might change in between!
+        unsigned int OUT_Head_copy = Ring_p->OUT_Head;
+
+        // we can write descriptors up to the point where we expect the
+        // result descriptors
+        if (Ring_p->IN_Tail < OUT_Head_copy)
+        {
+            // used positions are around the wrap point
+            // free positions are between the pointers
+            A = OUT_Head_copy - Ring_p->IN_Tail;
+        }
+        else
+        {
+            // used positions are between the two pointers
+            // rest is free
+            A = Ring_p->IN_Size - (Ring_p->IN_Tail - OUT_Head_copy);
+        }
+
+        // avoid filling the entire ring
+        // so we can differentiate full from empty
+        // (when it contains all commands or all results)
+        if (A != 0)
+            A--;
+    }
+
+    // limit based on provided descriptors
+    A = MIN(A, DescriptorCount);
+
+    // limit for sequential writing
+    N = MIN(A, (int)(Ring_p->IN_Size - Ring_p->IN_Tail));
+
+    // bail out early if there is no space
+    if (N == 0)
+    {
+        return 0;       // ## RETURN ##
+    }
+
+    W1 = Ring_p->CB.WriteFunc_p(
+                        Ring_p->CB.CallbackParam1_p,
+                        Ring_p->CB.CallbackParam2,
+                        /*WriteIndex:*/Ring_p->IN_Tail,
+                        /*WriteCount:*/N,
+                        /*AvailableSpace*/A,
+                        Descriptors_p,
+                        DescriptorCount,
+                        /*SkipCount:*/0);
+
+    if (W1 <= 0)
+    {
+        //  0: no descriptors could be added
+        // <0: failure
+        return W1;      // ## RETURN ##
+    }
+
+    if (W1 == N &&
+        W1 < DescriptorCount &&
+        A > N)
+    {
+        // we have written all possible positions up to the end of the ring
+        // now write the rest
+        N = A - N;
+
+        W2 = Ring_p->CB.WriteFunc_p(
+                            Ring_p->CB.CallbackParam1_p,
+                            Ring_p->CB.CallbackParam2,
+                            /*WriteIndex:*/0,
+                            /*WriteCount:*/N,
+                            /*AvailableSpace*/N,
+                            Descriptors_p,
+                            DescriptorCount,
+                            /*SkipCount:*/W1);
+
+        if (W2 < 0)
+        {
+            // failure
+            return W2;      // ## RETURN ##
+        }
+    }
+
+    // now update the position for the next write
+    {
+        unsigned int i = Ring_p->IN_Tail + W1 + W2;
+
+        // do not use % operator to avoid costly divisions
+        if (i >= Ring_p->IN_Size)
+            i -= Ring_p->IN_Size;
+
+        Ring_p->IN_Tail = i;
+    }
+
+    // return how many descriptors were added
+    return W1 + W2;
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Get
+ *
+ * This routine retrieves a number of descriptors from the result ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Get(
+        volatile RingHelper_t * const Ring_p,
+        const int ReadyCount,
+        void * Descriptors_p,
+        const int DescriptorsLimit)
+{
+    int A, N;
+    int R1, R2;
+
+    R2 = 0;
+
+#ifdef RINGHELPER_STRICT_ARGS
+    if (Ring_p == NULL ||
+        Descriptors_p == NULL ||
+        DescriptorsLimit < 0)
+    {
+        return -1;
+    }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+    if (DescriptorsLimit == 0 ||
+        ReadyCount == 0)
+    {
+        // no space in output buffer
+        // or no descriptors ready
+        return 0;
+    }
+
+    // calculate the maximum number of descriptors that can be retrieved
+    // sequentially from this read position, taking into account the
+    // DescriptorsLimit and the ReadyCount (if available)
+
+    // A = entries in result ring from read position till end
+    A = Ring_p->OUT_Size - Ring_p->OUT_Head;
+
+    N = MIN(A, DescriptorsLimit);
+
+    if (ReadyCount > 0)
+        N = MIN(N, ReadyCount);
+
+    // now retrieve this number of descriptors
+    R1 = Ring_p->CB.ReadFunc_p(
+                        Ring_p->CB.CallbackParam1_p,
+                        Ring_p->CB.CallbackParam2,
+                        /*ReadIndex:*/Ring_p->OUT_Head,
+                        /*ReadLimit:*/N,
+                        Descriptors_p,
+                        /*SkipCount:*/0);
+
+    if (R1 <= 0)
+    {
+        //  0: if we got nothing on the first call, we can stop here
+        // <0: error while reading
+        //     this means we cannot maintain read synchronization
+
+        return R1;      // ## RETURN ##
+    }
+
+    // if we got the maximum, we can try to read more
+    // after wrapping to the start of the buffer
+    if (R1 == N &&
+        R1 < DescriptorsLimit &&
+        R1 != ReadyCount)
+    {
+        // A = number of entries in ring up to previous read-start position
+        A = Ring_p->OUT_Head;
+
+        N = MIN(A, DescriptorsLimit - R1);
+
+        if (ReadyCount > 0)
+            N = MIN(N, ReadyCount - R1);
+
+        R2 = Ring_p->CB.ReadFunc_p(
+                            Ring_p->CB.CallbackParam1_p,
+                            Ring_p->CB.CallbackParam2,
+                            /*ReadIndex:*/0,        // start of buffer
+                            /*ReadLimit:*/N,
+                            Descriptors_p,
+                            /*SkipCount:*/R1);
+
+        if (R2 < 0)
+        {
+            // failure
+            return R2;      // ## RETURN ##
+        }
+    }
+
+    // now update the position for the next read
+    {
+        unsigned int i = Ring_p->OUT_Head + R1 + R2;
+
+        // do not use % operator to avoid costly divisions
+        if (i >= Ring_p->OUT_Size)
+            i -= Ring_p->OUT_Size;
+
+        Ring_p->OUT_Head = i;
+    }
+
+    // return the number of descriptors read
+    return R1 + R2;
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_FillLevel_Get
+ *
+ * This function return a number of filled (used) descriptors in the ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_FillLevel_Get(
+        volatile RingHelper_t * const Ring_p)
+{
+#ifdef RINGHELPER_STRICT_ARGS
+    if (Ring_p == NULL)
+    {
+        return -1;
+    }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+    // out of the descriptors provided, calculate the maximum number of
+    // descriptors that can be written sequentially before the ring is full.
+    if (Ring_p->fSeparate)
+    {
+        // separate rings
+
+        return -1; // not implemented
+    }
+    else
+#endif  /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+    {
+        // combined rings
+
+        unsigned int FillLevel;
+        unsigned int OUT_Head_copy;
+
+        // Critical: we have to be careful not to read the OUT_Head more
+        //           than one, since it might change in between!
+        OUT_Head_copy = Ring_p->OUT_Head;
+
+        if (Ring_p->IN_Tail < OUT_Head_copy)
+        {
+            // used positions are around the wrap point
+            // free positions are between the pointers
+            FillLevel = Ring_p->IN_Size - (OUT_Head_copy - Ring_p->IN_Tail);
+        }
+        else
+        {
+            // used positions are between the two pointers
+            // rest is free
+            FillLevel = Ring_p->IN_Tail - OUT_Head_copy;
+        }
+
+        // avoid filling the entire ring
+        // so we can differentiate full from empty
+        // (when it contains all commands or all results)
+        if (FillLevel < Ring_p->IN_Size)
+            FillLevel++;
+
+        return (int)FillLevel;
+    }
+}
+
+
+/* end of file ringhelper.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/DMABuf API Implementation Notes.txt b/package-21.02/kernel/crypto-eip/src/ddk/slad/DMABuf API Implementation Notes.txt
new file mode 100644
index 0000000..74aa78d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/DMABuf API Implementation Notes.txt
@@ -0,0 +1,118 @@
++=============================================================================+
+| Copyright (c) 2010-2020 Rambus, Inc. and/or its subsidiaries.               |
+|                                                                             |
+| Subject   : DMABuf API Implementation Notes                                 |
+| Product   : SLAD API                                                        |
+| Date      : 18 November, 2020                                               |
+|                                                                             |
++=============================================================================+
+
+SLAD API Implementation Notes : DMABuf API
+==========================================
+
+The SLAD API is a set of the API's one of which is the DMA Buffer
+Allocation (DMABuf) API. The driver implementation specifics of these APIs
+are described in short documents that serve as an addendum to the API
+specifications. This document describes the DMABuf API.
+
+
+DMABuf API
+----------
+
+The implementation of this API is fully re-entrant.
+
+Supported properties:
+     Alignment must be 1, 2, 4, 8, 16, 32, 64 or 128.
+     Bank is used to select a memory pool suitable for certain data types.
+     fCached can be used to indicate whether a DMA resource is cached.
+     Implementations of the DMAResource API can ignore the fCached parameter
+     and force all buffers to be allocated or registered either
+     cached or non-cached.
+
+DMABuf_NULLHandle:
+     Implemented as a NULL handle that can be assigned to a variable
+     of type DMABuf_Handle_t
+
+DMABuf_Handle_IsSame:
+     Two pointers to memory locations where the handles are stored
+     should be provided to this function as parameters.
+     The function will do byte comparison for the size of the handle type.
+
+DMABuf_Alloc:
+     Maximum buffer size supported is 1 megabyte.
+     Implementation uses the DMAResource API
+
+DMABuf_Register:
+     Supported values for AllocatorRef:
+     'N' to register a buffer that is not intended to be DMA-safe but for
+         which a DMABuf handle is desired nevertheless.
+     'R' to register a (subrange of) a buffer previously allocated with
+         DMABuf_Alloc. This buffer is known to be DMA-safe.
+     'k' to register a buffer allocated with Linux kmalloc.
+     'C' to register a coherent DMA-mapped buffer. The application must
+         provide the bus address in Alternative_p.
+
+     Alternative_p is only used with allocator ref 'C' and should be set to
+     "NULL" for other allocators.
+
+     All implementations of the DMAResource API support the 'N' and 'R'
+     allocators. The 'k' and 'C' allocators are only supported by
+     the Linux kernel implementation.
+
+DMABuf_Release:
+     The implementation is protected against invalid handles and also detects
+     and warns when handles are used after release (does not work well when
+     all available handles are in use).
+
+Banks:
+     The implementation supports several banks. The banks are configurable,
+     an example default configuration is as follows
+     (bank values in DMABuf_Properties_t):
+
+     - Bank 0 allocates buffers anywhere in physical RAM without restrictions.
+
+     - Bank 1 allocates buffers suitable for SA records and Transform records.
+       All these are required to lie in a single 4GB segment on 64-bit systems.
+
+     - Bank 2 allocates buffers suitable for flow records. All these are
+       required to lie in a single 4GB segment on 64-bit systems.
+
+The following properties of the static (fixed-size) DMA banks are implemented:
+
+     - One static bank contains one DMA pool;
+
+     - One DMA Pool contains a fixed compile-time configurable number of blocks;
+
+     - All blocks in one DMA pool have the same fixed compile-time configurable
+       size;
+
+     - The DMA pools for all the configured static banks are allocated
+       in DMAResource_Init() and freed in DMAResource_Uninit();
+
+     - DMA resources can be allocated in a static bank using
+       DMABuf_Alloc() and they must be freed using DMABuf_Release();
+
+     - Only sub-sets of DMA resources allocated in a static bank can be
+       registered in that bank using DMABuf_Register();
+       If the DMABuf_Register() function is called for a static
+       bank then it must use allocator type 82 ('R') and the required memory
+       block must belong to an already allocated DMA resource in that bank;
+
+     - The DMABuf_Register() function can be called for a static
+       bank also using allocator type 78 ('N') to register a DMA-unsafe buffer;
+       These DMA resources must be subsequently freed using the DMABuf_Release()
+       function;
+
+     - An "all-pool" DMA resource of size (nr_of_blocks * block_size) can be
+       allocated in a static bank using DMABuf_Alloc() where nr_of_blocks
+       and block_size are compile-time configuration parameters
+       (see HWPAL_DMARESOURCE_BANKS in c_dmares_gen.h);
+       The DMABuf_Register() function can be used to register
+       sub-sets of this DMA resource; Only one such a all-pool DMA resource
+       can be allocated in one static bank and must be freed using
+       DMABuf_Release() function;
+
+     - No other DMA resources can be allocated in a static bank
+       where an all-pool DMA resource is allocated.
+
+<end of document>
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/PCL API Implementation Notes.txt b/package-21.02/kernel/crypto-eip/src/ddk/slad/PCL API Implementation Notes.txt
new file mode 100644
index 0000000..c1db340
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/PCL API Implementation Notes.txt
@@ -0,0 +1,150 @@
++=============================================================================+
+| Copyright (c) 2012-2020 Rambus, Inc. and/or its subsidiaries.               |
+|                                                                             |
+| Subject   : PCL API Implementation Notes                                    |
+| Product   : PCL API                                                         |
+| Date      : 18 November, 2020                                               |
+|                                                                             |
++=============================================================================+
+
+The SLAD API is a set of the APIs one of which is the Packet Classification
+(PCL) API. The driver implementation specifics of these APIs are
+described in short documents that serve as an addendum to the API
+specifications. This document describes the PCL API.
+
+This document uses the phrase "configurable" to indicate that a parameter or
+option is build-time configurable in the driver. Please refer to the User Guide
+of the driver for details.
+
+
+PCL API
+-------
+
+The PCL API manages two types of data structures relevant to the
+Packet Classification Engine: flow data structures and transform data
+structures.
+
+The PCL API is not used to submit packets (command descriptors) to the
+Packet Engine and to retrieve result descriptors (referring to
+processed packets). This is performed by the PEC API (see the PEC API
+Implementation Notes for details.
+
+Transform records
+     Transform records are allocated outside the Driver (using the
+     DMABuf API) and are initialized outside the Driver by the
+     Extended SA Builder. The Extended SA Builder is the SA Builder
+     that is compiled with the "Extended" configuration option
+     enabled. Transform records are represented by their DMABuf
+     Handle. They can be registered with PCL_Transform_Register() before
+     they are used and they are unregistered by
+     PCL_Transform_Unregister() after use. A subset of the contents
+     (sequence number and statistics) can be read with
+     PCL_Transform_Get_ReadOnly().
+
+Flow records
+     Flow Records are represented by an internal data structure
+     (represented by PCL_FlowHandle_t), which is invisible to the application.
+     The internal data structure is allocated within the Driver.
+     A DMA-safe buffer is associated with it and this is also allocated
+     within the Driver and invisible to the application.
+
+     The Driver makes use of the internal DMAResource API to allocate
+     the DMA-safe buffer and of an internal memory allocation API
+     (adapter_alloc.h) to allocate the data structure.
+
+     Allocation of flow records can be a time consuming operation and
+     it may not be allowed at all in certain situations (e.g. in
+     interrupt context). Therefore allocating and deallocating the
+     resources for a flow record is decoupled from adding and removing
+     flow records in the flow record table.
+
+     When a flow record is allocated with PCL_Flow_Alloc() its
+     resources (internal data structure and DMA-safe buffer) are
+     allocated, but the flow record is not initialized, is not part of
+     the flow table and is inaccessible to the Packet Classification
+     Engine. PCL_Flow_Add() initializes the record and adds it to a
+     lookup table. The size of the hash table from which flow lookup
+     is started has a configurable size.
+
+     PCL_Flow_Get_ReadOnly() reads the variable fields (last used time,
+     packet statistics) from a flow record. PCL_Flow_Remove() removes it
+     from the lookup table. At this time the resources are still allocated
+     and can be reused by another flow record. PCL_Flow_Release() deallocates
+     all flow resources.
+
+     This implementation does not implement the PCL_Flow_Lookup() function.
+
+Direct Transform Lookup
+     Transform records can be looked up directly (without the need for
+     a flow record). Use the function PCL_DTL_Transform_Add to add an
+     existing record (already registered with PCL_Transform_Register)
+     to the lookup table. PCL_DTL_Transform_Remove removes the transform
+     record from the lookup table again.
+
+Record invalidation
+     When flow records or transform records must be removed from the
+     system, they must also be removed from the record cache of the packet
+     engine, by means of a special command descriptor. The following
+     steps are required:
+     - Prevent the record from being looked up again. Use PCL_Flow_Remove
+       to remove a flow record from the lookup table. Use
+       PCL_DTL_Transform_Remove to remove a transform record from the lookup
+       table.
+     - Submit a special command descriptor containing a record invalidation
+       command with PEC_Packet_Put.
+     - Wait until the corresponding result descriptor is received with
+       PEC_Packet_Get.
+
+Byte ordering (endianness)
+     The transform buffers are considered arrays of 32-bit integers, in host-
+     native byte ordering. The driver will change the byte order if this is
+     required (configurable). The data buffers are considered byte arrays and
+     the driver will not touch these. Flow records are allocated and managed
+     entirely by the driver and their internal representation is never used by
+     the application.
+
+Bounce Buffers
+     The PCL API does not use bounce buffers. Transform buffers can be
+     allocated by the application in a DMA-safe way and buffers for the
+     flow table are allocated entirely within the Driver.
+
+Banks for DMA resources.
+     The PCL API requires that all DMA buffers for transform records
+     are allocated in Bank 1 (Bank parameter in
+     DMABuf_Properties_t). Internally the PCL adapter takes care of
+     allocating DMA-safe buffers for flow records in Bank 2. Memory
+     allocations in Bank 1 and Bank 2 are taken from special-purpose
+     memory pools. On 64-bit systems these pools are guaranteed to lay
+     in a 4GB address range. The PCL implementation takes care to convert
+     64-bit bus addresses for flow and transform records to 32-bit offsets
+     with respect to the base address of the pool.
+
+Concurrent Context Synchronization (CCS)
+     The PCL API implementation supports one single multi-threaded application,
+     allowing concurrent and independent use of PCL_Init/UnInit, PCL_Flow and
+     PCL_Transform functions. Multiple applications for the PCL API are
+     not supported.
+
+     The PCL API implementation provides synchronization mechanisms for
+     concurrent contexts invoking the API functions. The API can be used
+     by multi-threaded user-space or kernel-space applications. The latter
+     can invoke the API functions from the user process as well as from softirq
+     contexts. Mixing user process execution with softirq contexts is also
+     supported. Both Linux Uni-Processor (UP) and Symmetric Multi-Processor
+     (SMP) kernel configurations are supported.
+
+     All the PCL API functions allow for just one execution context at a time.
+     Note that although the API functions take the interface ID as an input
+     parameter it is not used in the current implementation.
+
+     The PCL API implementation serializes the access from concurrent execution
+     contexts to the classification device so having multiple contexts using
+     this API will not result in better performance.
+
+     When a function from the PCL API detects that it competes for a resource
+     already used at the time by another context executing the PCL code it will
+     not block and return PCL_STATUS_BUSY return code. The caller should try
+     calling this function again short after.
+
+
+<end of document>
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/PEC API Implementation Notes.txt b/package-21.02/kernel/crypto-eip/src/ddk/slad/PEC API Implementation Notes.txt
new file mode 100644
index 0000000..67c1e5e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/PEC API Implementation Notes.txt
@@ -0,0 +1,347 @@
++=============================================================================+
+| Copyright (c) 2010-2022 Rambus, Inc. and/or its subsidiaries.               |
+|                                                                             |
+| Subject   : PEC API Implementation Notes                                    |
+| Product   : SLAD API                                                        |
+| Date      : 02 December, 2022                                               |
+|                                                                             |
++=============================================================================+
+
+The SLAD API is a set of the API's one of which is the Packet Engine
+Control (PEC) API. The driver implementation specifics of these APIs are
+described in short documents that serve as an addendum to the API
+specifications. This document describes the PEC API.
+
+This document uses the phrase "configurable" to indicate that a parameter or
+option is build-time configurable in the driver. Please refer to the User Guide
+of the driver for details.
+
+
+PEC API
+-------
+
+One PEC implementation is available: ARM (Autonomous Ring Mode).
+
+Packet engine device
+     The PEC API implementation can support multiple packet processing
+     devices. These devices are identified by the interface ID parameter
+     in the PEC API functions and are sometimes referred to as rings.
+
+ARM mode
+     ARM mode uses DMA, can queue many jobs, handles commands and
+     results asynchronously (but always in-order) and also supports
+     fragmented data buffers (scatter / gather). The implementation
+     supports a single multi-threaded application per ring, allowing
+     concurrent and independent use of PEC_SA_Register,
+     PEC_SA_UnRegister, PEC_Packet_Put and PEC_Packet_Get. Both
+     PEC_Packet_Put and PEC_Packet_Get are not re-entrant, but
+     individual threads can use these functions concurrently.
+
+     Ensure that the Token Data, Packet Data and Context Data DMA
+     buffers are not re-used or freed by the execution context using
+     the PEC and DMABuf API's functions or by another execution
+     context until the processed result descriptor(s) referring to the
+     packet associated with these buffers is(are) fully processed by
+     the engine. This is required not only when in-place packet
+     transform is done using the same Packet Data DMA buffer as input
+     and output buffer but also when different DMA buffers are used
+     for the packet processing input and output data.
+
+Byte ordering (endianess)
+     The SA and Token buffers are considered arrays of 32bit integers,
+     in host-native byte ordering. The driver will change the byte
+     order if required if this is required (configurable).  The data
+     buffers are considered byte arrays and the driver will not touch
+     these.
+
+Bounce Buffers
+     Bounce Buffer support can be removed (configurable) from the driver to
+     reduce footprint.
+     For ARM mode, the implementation can bounce the SA, Token and data buffers
+     if these are not DMA-safe. This requires that the buffer was registered
+     using DMABuf_Register with an unsupported AllocatorRef.
+     When bouncing an SA buffer, it will be copied to a bounce buffer in
+     PEC_SA_Register and copied back by PEC_SA_UnRegister.
+     When bouncing a token buffer, a bounce buffer is created by
+     PEC_Packet_Put and released by PEC_Packet_Get.
+     When bouncing a data buffer (because either the source or destination
+     requires bouncing), a single bounce buffer is created by PEC_Packet_Put
+     based on the largest of the source and destination buffers. The engine
+     then performs an in-place operation in the bounce buffer. PEC_Packet_Get
+     copies the result to the destination buffer and releases the bounce
+     buffer.
+
+Descriptor grouping
+     PEC_Packet_Get and PEC_Packet_Put can process up to a
+     configurable number of descriptors in one call.
+
+Queuing
+     The ring can queue a configurable number of jobs. This can be set to
+     hundreds or even thousands, at the cost of some memory footprint. This
+     can avoid queuing in software and can also give better performance
+     (avoids idle engine due to empty ring).
+
+Scatter / Gather support
+     The ARM mode supports the scatter/gather extension (configurable) of the
+     PEC API.
+     If the SrcPkt_Handle in the command descriptor is a PEC SG_List, a
+     packet is assumed to used gather.
+     If the DstPkt_Handle in the command descriptor is a PEC SG_List, a
+     packet is assumed to used scatter.
+
+     The application is responsible for setting up both the gather list
+     in SrcPkt_Handle and the scatter list in DstPkt_Handle for each packet.
+     The application is responsible for allocating and releasing the individual
+     gather and scatter buffers.
+
+     The buffers used for the Scatter and/or Gather data are not bounced and
+     must be allocated and provided to the driver as DMA-safe buffers. This
+     can be achieved by using the driver's DMABuf API.
+
+Continuous Scatter mode
+     The ARM mode supports continuous scatter mode, which can be enabled per
+     ring. When continuous scatter mode is enabled for a ring, the result
+     packets are written to a sequence of destination buffers supplied by the
+     function PEC_Scatter_Preload(). Each result packet will occupy one
+     or more destination buffers (it will be scattered), depending on the
+     packet length and the sizes of the destination buffers.
+
+     It is not determined in advance which destination buffers will be
+     used for the result packet of a certain PEC_Packet_Put(). In a
+     typical use case, the application will pre-allocate a number of
+     buffers, each of the same size, and submits them to the
+     PEC_Scatter_Preload() function. It will regularly call
+     PEC_Scatter_Preload() to refill the supply of destination buffers, after
+     buffers are used by result packets.
+
+     Continuous scatter mode can be used even if the driver is configured
+     without scatter-gather support, but in that case each packet is required
+     to fit into a single destination buffer.
+
+     Continuous scatter mode is not supported with LAC flows.
+
+Redirection
+     Some configurations of the hardware support redirection. A packet,
+     originally submitted with PEC_Packet_Put() can have its result appear
+     on a different ring or on the inline interface. A packet, originally
+     received on the inline interface, can have its result appear on
+     a ring.
+
+     Any ring from which packets can be redirected, must be configured with
+     continuous scatter mode. Any ring towards which packets can be redirected,
+     must be configured with continuous scatter mode. When redirection is
+     possible, the sequence of packets submitted with PEC_Packet_Put() and
+     the sequence of result packets retrieved with PEC_Packet_Get()
+     on the same ring are no longer related to one another.
+
+     When a packet submitted with PEC_Packet_Put() is redirected to the
+     inline interface, no result descriptor will be received with
+     PEC_Packet_Get(). When a packet is received on the inline interface and
+     it is redirected to a ring, a result descriptor will appear with no
+     corresponding command descriptor in PEC_Packet_Put().
+
+Command Descriptor fields
+     User_p is fully supported on rings that do not use continuous scatter mode
+     and allows the user to match results to commands. User_p is not supported
+     on rings with continuous scatter mode.
+
+     The Control1 field is not used by this implementation. The PEC
+     API function PEC_CD_Control_Write is not implemented. Instead use
+     the IOToken API to pass an array of 32-bit words via the
+     InputToken_p field. The application is responsible for allocating
+     this array. The HW_Services field in the data structure passed to
+     the IOToken API specifies the exact packet flow or alternatively
+     it can specify a record invalidation command instead.  The values
+     to be filled in are provided by the firmware API.
+
+     Control2 can be used to specify the engine on which a packet must be
+     processed. This can be useful for protocols like TLS, where subsequent
+     packets of the same data stream must be processed on the same engine to
+     ensure in-order processing and in-order assignment of the sequence numbers.
+     Bit 5 in Control2 can be set if the engine is specified. The engine ID
+     is put in bits 4..0. Otherwise, the Control2 field should be all zero.
+
+     LAC packet flow:
+     - A valid Token_Handle must always be provided for each packet and
+       Token_WordCount must be set to the exact size in words of the token.
+     - SA_Handle1 must point to the main SA, which must be registered by
+       PEC_SA_Register.
+     - SA_Handle2 must be a null handle
+     - SA_WordCount is not used.
+     - DstPkt_Handle must always be provided, also for input-only operations.
+       When no destination buffer is required, it can be set to SrcPkt_Handle.
+     - The TokenHeaderWord passed to the IOToken API must be filled in.
+     - The Offset_ByteCount passed to the IOToken API is not used.
+
+     Other packet flows:
+     - Token_Handle is the null handle and Token_WordCount is zero.
+     - SA_Handle1 is the null handle if classification is used, else it is the
+       DMABuf handle representing a transform record.
+     - SA_Handle2 must be a null handle
+     - SA_WordCount is not used.
+     - DstPkt_Handle must always be provided (except for continuous
+       scatter mode), also for input-only operations.
+       When no destination buffer is required, it can be set to SrcPkt_Handle.
+       When continuous scatter mode is enabled, no destination handle must be
+       provided.
+     - The Offset_ByteCount field passed to the IOTOken API specifies the
+       number of bytes at the start of each packet that will be passed
+       unchanged and are not part of the packet to be processed.
+     - The NextHeader field passed to the IOToken API specifies the Next
+       Header field for IPsec packet flows that do not use network header
+       processing.
+
+     Record invalidation commands:
+     - Token_Handle is the null handle and Token_WordCount is zero.
+     - SA_Handle must point to the SA, transform or flow record to be
+       invalidated.
+     - SA_Handle2 must be a null handle
+     - SA_WordCount is not used.
+     - SrcPkt_Handle and DstPkt_Handle must both be null handles.
+     - SrcPkt_ByteCount is zero.
+
+     Note: A record invalidation command may be submitted via the PEC API
+           to the engine only when the engine has no packets being processed
+           for this record.
+
+Result Descriptor fields
+     User_p is fully supported on rings that do not use continuous scatter mode
+     and allows the user to match results to commands. User_p is not supported
+     on rings with continuous scatter mode.
+
+     SrcPkt_Handle and DstPkt_Handle are the same as provided in the command
+     descriptor. DstPkt_p is the host address for DstPkt_Handle.
+     On ring with continuous scatter mode, these fields are the NULL handle
+     and NULL pointer. On rings with continuous scatter mode, the NumParticles
+     field will be the number of scatter buffers used by the result packet.
+     At least one scatter buffer will be used, even if the result packet
+     has zero length. In some cases, the number of scatter buffer is
+     higher that would be required by the result packet.
+
+     DstPkt_ByteCount and Bypass_WordCount have been extracted from the engine
+     result descriptor as described in the engine datasheet under PE_LENGTH.
+     Bypass_WordCount should be the same as was provided in the command
+     descriptor.
+
+     For operations that do not require output buffers such as hash operations
+     the SrcPkt_Handle and DstPkt_Handle parameters in the
+     PEC_CommandDescriptor_t descriptor must be set equal by applications.
+     The advantage of this solution is that the driver still checks that
+     the output buffer handle is not NULL for all operations and can detect
+     errors in applications that do not do provide correct output buffer handle.
+     The disadvantage is that for hash operations this will degrade performance
+     because the driver will have to perform bounce buffer copy back to
+     the original buffer which is not needed and the driver will also
+     perform the PostDMA operation which is also not needed.
+
+     Status1 and Status2 reflect up to two words from the result token that
+     contain relevant status information. Use the function
+     PEC_RD_Status_Read to extract this information in an
+     engine-independent form.
+
+     More status information is passed in an array of 32-bit words via
+     the OutputToken_p field. The IOToken API can be used to extract
+     information from this array. The application is responsible for allocating
+     this array before the call to PEC_Packet_Get.
+
+Notify Requests (callbacks)
+     In ARM mode, two notify requests (commands and results) are
+     supported.  The result notification callback is only invoked in
+     interrupt mode.  The command notification callback is invoked
+     from within PEC_Packet_Get.
+
+SA Invalidation
+     In order to remove an SA from the system, it is required to carry out
+     the following operations in the specified order.
+     - Submit a special command descriptor with a transform record invalidation
+       command via PEC_Packet_Put(). This command will remove the record from
+       the record cache of the packet engine.
+     - Wait until the corresponding result descriptor is received via
+       PEC_Packet_Get().
+     - Call PEC_SA_UnRegister(). This command will take care of CPU cache
+       coherency, endianness conversion and bounce buffers, whichever applies.
+     - At this time the DMA buffer of the SA can be reused for a different
+       purpose or it can be freed.
+
+Banks for DMA resources
+     DMA-safe buffers for each data type must be allocated with the
+     correct Bank parameter (in DAMBuf_Properties_t).
+     Buffers for SA records must be allocated with Bank=1, all other
+     buffers must be allocated with Bank=0. On 64-bit hosts, SA buffers
+     must be allocated in a 4GB memory range, which is taken care of by
+     using Bank=1.
+
+SA resources
+     The functions PEC_SA_Register and PEC_SA_UnRegister take three
+     DMABuf handles as parameters. The first of these is always the
+     DMABuf handle representing the SA, the second is always a null
+     handle and the third is the null handle if the SA does not have
+     an ARC4 state record.
+
+     If the SA does have an ARC4 state record, the SA_Handle3
+     parameter represents the ARC4 state record. However this DMABuf
+     handle is supposed to represent the ARC4 state part within the SA
+     buffer. The application is supposed to use DMABuf_Register
+     (AllocatorRef=='R') to register a subset of the SA buffer as a
+     DMA Handle.
+
+Multiple Applications
+     The current implementation supports multiple rings (tested with
+     two rings) and each ring can be used by a separate application,
+     independently of other rings. The applications can run
+     concurrently, as long as each application uses a different
+     ring. The use of PEC_Packet_Put and PEC_Packet_Get by different
+     concurrent applications requires no locking. The implementation
+     of PEC_SA_UnRegister contains the required locking to support
+     multiple applications.
+
+Concurrent Context Synchronization (CCS)
+     The PEC API implementation supports a single multi-threaded application
+     per interface ID, allowing concurrent and independent use of
+     PEC_SA_Register, PEC_SA_UnRegister, PEC_Packet_Put and PEC_Packet_Get.
+     Multiple applications using the PEC API are also supported but they must
+     use different interface ID each.
+
+     Note: although the PEC_SA_Register and PEC_SA_UnRegister functions take
+           InterfaceId as an input parameter it is ignored by these functions
+           since this functions do nothing what is specific to an packet I/O
+           (ring) interface.
+
+     The PEC API implementation provides synchronization mechanisms for
+     concurrent contexts invoking the API functions. The API can be used
+     by multi-threaded user-space and kernel-space applications. The latter
+     can invoke the API functions from the user process as well as from softirq
+     contexts. Mixing user process execution with softirq contexts is also
+     supported. Both Linux Uni-Processor (UP) and Symmetric Multi-Processor
+     (SMP) kernel configurations are supported.
+
+     The PEC API allows for non-blocking synchronization concurrent context
+     invoking the API functions for different interface ID's. The only
+     exception are the PEC_Init and PEC_UnInit functions which both allow
+     for just one execution context at a time even for different interface ID's.
+     Also there should be no contexts executing the PEC_Packet_Put
+     or PEC_Packet_Get function code in order for the PEC_UnInit function
+     to succeed for the same interface ID.
+
+     For optimal utilization of the packet engine the PEC API user should allow
+     for concurrent contexts for the PEC_Packet_Put and PEC_Packet_Get
+     functions for the same interface ID. Note that having multiple concurrent
+     contexts invoking the PEC_Packet_Put function for the same interface ID
+     will not improve performance because this function does not allow more
+     than one execution context at a time for one interface ID. The same
+     applies for the PEC_Packet_Get function.
+
+     When a function from the PEC API detects that it competes for a resource
+     already used at the time by another context executing the PEC code it will
+     not block and return PEC_STATUS_BUSY return code. The caller should try
+     calling this function again short after.
+
+Debugging
+     The PEC_Put_Dump() and PEC_Get_Dump() functions can be used to print
+     the command ring and result ring administration and cached data as well
+     as the content of the ring buffers respectively. A slot corresponds to
+     a descriptor in the ring. These functions can be used to debug the packet
+     I/O functionality.
+
+
+<end of document>
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_dmabuf.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_dmabuf.c
new file mode 100644
index 0000000..790f478
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_dmabuf.c
@@ -0,0 +1,404 @@
+/* adapter_dmabuf.c
+ *
+ * Implementation of the DMA Buffer Allocation API.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// DMABuf API
+#include "api_dmabuf.h"
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Logging API
+#include "log.h"
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"
+#include "dmares_mgmt.h"
+#include "dmares_buf.h"
+#include "dmares_addr.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcmp
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * DMABuf_NULLHandle
+ *
+ */
+const DMABuf_Handle_t DMABuf_NULLHandle = { NULL };
+
+// Initial DMA buffer alignment setting
+static int Adapter_DMABuf_Alignment = ADAPTER_DMABUF_ALIGNMENT_INVALID;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMABuf_Handle2DMAResourceHandle
+ */
+DMAResource_Handle_t
+Adapter_DMABuf_Handle2DMAResourceHandle(
+        DMABuf_Handle_t Handle)
+{
+    if (Handle.p == NULL)
+    {
+        return NULL;
+    }
+    else
+    {
+        return (DMAResource_Handle_t)Handle.p;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_Handle2DMABufHandle
+ */
+DMABuf_Handle_t
+Adapter_DMAResource_Handle2DMABufHandle(
+        DMAResource_Handle_t Handle)
+{
+    DMABuf_Handle_t DMABuf_Handle;
+
+    DMABuf_Handle.p = Handle;
+
+    return DMABuf_Handle;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_IsForeignAllocated
+ */
+bool
+Adapter_DMAResource_IsForeignAllocated(
+        DMAResource_Handle_t Handle)
+{
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(Handle);
+
+    if(!Rec_p)
+    {
+        return false;
+    }
+    else
+    {
+        return (Rec_p->AllocatorRef != 'A' && Rec_p->AllocatorRef != 'R');
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_HostAddr
+ */
+void *
+Adapter_DMAResource_HostAddr(
+        DMAResource_Handle_t Handle)
+{
+    DMAResource_AddrPair_t HostAddr;
+
+    DMAResource_Translate(Handle, DMARES_DOMAIN_HOST, &HostAddr);
+
+    return HostAddr.Address_p;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_IsSubRangeOf
+ *
+ * Return true if the address range defined by Handle1 is
+ * within the address range defined by Handle2.
+ */
+bool
+Adapter_DMAResource_IsSubRangeOf(
+        const DMAResource_Handle_t Handle1,
+        const DMAResource_Handle_t Handle2)
+{
+    DMAResource_AddrPair_t AddrPair1, AddrPair2;
+
+    DMAResource_Translate(Handle1, DMARES_DOMAIN_HOST, &AddrPair1);
+    DMAResource_Translate(Handle2, DMARES_DOMAIN_HOST, &AddrPair2);
+
+    if (AddrPair1.Domain == AddrPair2.Domain)
+    {
+        const uint8_t * Addr1 = AddrPair1.Address_p;
+        const uint8_t * Addr2 = AddrPair2.Address_p;
+        const DMAResource_Record_t * const Rec1_p =
+                                DMAResource_Handle2RecordPtr(Handle1);
+        const DMAResource_Record_t * const Rec2_p =
+                                DMAResource_Handle2RecordPtr(Handle2);
+
+        if ((Rec1_p->Props.Size <= Rec2_p->Props.Size) &&
+            (Addr2 <= Addr1) &&
+            ((Addr1 + Rec1_p->Props.Size) <= (Addr2 + Rec2_p->Props.Size)))
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_Alignment_Set
+ */
+void
+Adapter_DMAResource_Alignment_Set(
+        const int Alignment)
+{
+    Adapter_DMABuf_Alignment = Alignment;
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_DMAResource_Alignment_Get
+ */
+int
+Adapter_DMAResource_Alignment_Get(void)
+{
+    return Adapter_DMABuf_Alignment;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Handle_IsSame
+ */
+bool
+DMABuf_Handle_IsSame(
+        const DMABuf_Handle_t * const Handle1_p,
+        const DMABuf_Handle_t * const Handle2_p)
+{
+    if (memcmp(Handle1_p, Handle2_p, sizeof(DMABuf_Handle_t)) == 0)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Alloc
+ */
+DMABuf_Status_t
+DMABuf_Alloc(
+        const DMABuf_Properties_t RequestedProperties,
+        DMABuf_HostAddress_t * const Buffer_p,
+        DMABuf_Handle_t * const Handle_p)
+{
+    DMAResource_Handle_t DMAHandle;
+    DMAResource_AddrPair_t AddrPair;
+    DMAResource_Properties_t ActualProperties;
+
+    ZEROINIT(AddrPair);
+    ZEROINIT(ActualProperties);
+
+    if (Handle_p == NULL ||
+        Buffer_p == NULL)
+    {
+        return DMABUF_ERROR_BAD_ARGUMENT;
+    }
+
+    // initialize the output parameters
+    Handle_p->p = NULL;
+    Buffer_p->p = NULL;
+
+    ActualProperties.Size       = RequestedProperties.Size;
+    ActualProperties.Bank       = RequestedProperties.Bank;
+    ActualProperties.fCached    = RequestedProperties.fCached;
+
+    if (Adapter_DMABuf_Alignment != ADAPTER_DMABUF_ALIGNMENT_INVALID &&
+        RequestedProperties.Alignment < Adapter_DMABuf_Alignment)
+        ActualProperties.Alignment = Adapter_DMABuf_Alignment;
+    else
+        ActualProperties.Alignment = RequestedProperties.Alignment;
+
+    if( !DMAResource_Alloc(ActualProperties,&AddrPair,&DMAHandle) )
+    {
+        // set the output parameters
+        Handle_p->p = (void*)DMAHandle;
+        Buffer_p->p = AddrPair.Address_p;
+
+        LOG_INFO("DMABuf_Alloc: allocated handle=%p, host addr=%p, "
+                 "alignment requested/actual %d/%d, "
+                 "bank requested %d, cached requested %d\n",
+                 Handle_p->p,
+                 Buffer_p->p,
+                 RequestedProperties.Alignment,
+                 ActualProperties.Alignment,
+                 RequestedProperties.Bank,
+                 RequestedProperties.fCached);
+
+        return DMABUF_STATUS_OK;
+    }
+    else
+    {
+        return DMABUF_ERROR_OUT_OF_MEMORY;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Register
+ */
+DMABuf_Status_t
+DMABuf_Register(
+        const DMABuf_Properties_t RequestedProperties,
+        void * Buffer_p,
+        void * Alternative_p,
+        const char AllocatorRef,
+        DMABuf_Handle_t * const Handle_p)
+{
+    DMAResource_Handle_t DMAHandle;
+    char ActualAllocator;
+    DMAResource_AddrPair_t AddrPair;
+    DMAResource_Properties_t ActualProperties;
+
+    ZEROINIT(AddrPair);
+    ZEROINIT(ActualProperties);
+
+    if (Handle_p == NULL ||
+        Buffer_p == NULL)
+    {
+        return DMABUF_ERROR_BAD_ARGUMENT;
+    }
+
+    // initialize the output parameter
+    Handle_p->p = NULL;
+
+    ActualProperties.Size       = RequestedProperties.Size;
+    ActualProperties.Bank       = RequestedProperties.Bank;
+    ActualProperties.fCached    = RequestedProperties.fCached;
+
+    if (Adapter_DMABuf_Alignment != ADAPTER_DMABUF_ALIGNMENT_INVALID &&
+        RequestedProperties.Alignment < Adapter_DMABuf_Alignment)
+        ActualProperties.Alignment = Adapter_DMABuf_Alignment;
+    else
+        ActualProperties.Alignment = RequestedProperties.Alignment;
+
+    ActualAllocator = AllocatorRef;
+
+    if( AllocatorRef == 'k'  || AllocatorRef == 'N' || AllocatorRef == 'R'
+        || AllocatorRef == 'C')
+    {
+        // 'N' is used to register buffers that do not need to be DMA-safe.
+        // 'R' is used to register (subranges of) buffers that are already
+        //     allocated with DMAResource_Alloc()/DMABuf_Alloc().
+        // 'k' is supported for Linux kmalloc() allocator only,
+        //     e.g. AllocatorRef = 'k' for streaming DMA mappings
+        // 'C' is supported for coherent buffers.
+        AddrPair.Domain     = DMARES_DOMAIN_HOST;
+        AddrPair.Address_p  = Buffer_p;
+    }
+    else if( AllocatorRef == 0 )
+    {
+        // Linux kmalloc() allocator is used,
+        // e.g. AllocatorRef = 'k' for streaming DMA mappings
+        ActualAllocator = 'k';
+        AddrPair.Domain     = DMARES_DOMAIN_HOST;
+        AddrPair.Address_p  = Buffer_p;
+    }
+    else
+    {
+        return DMABUF_ERROR_BAD_ARGUMENT;
+    }
+
+    if( DMAResource_CheckAndRegister(ActualProperties,AddrPair,
+            ActualAllocator,&DMAHandle) == 0 )
+    {
+        if( ActualAllocator == 'C' )
+        {
+            // Add bus address for the resource for AllocatorRef = 'C'
+            AddrPair.Domain     = DMARES_DOMAIN_BUS;
+            AddrPair.Address_p  = Alternative_p;
+
+            DMAResource_AddPair(DMAHandle,AddrPair);
+        }
+
+        // set the output parameters
+        Handle_p->p = (void*)DMAHandle;
+
+        LOG_INFO("DMABuf_Register: registered handle=%p, host addr=%p, "
+                 "allocator=%d, alignment requested/actual %d/%d, "
+                 "bank requested %d, cached requested %d\n",
+                 Handle_p->p,
+                 Buffer_p,
+                 AllocatorRef,
+                 RequestedProperties.Alignment,
+                 ActualProperties.Alignment,
+                 RequestedProperties.Bank,
+                 RequestedProperties.fCached);
+
+        return DMABUF_STATUS_OK;
+    }
+    else
+    {
+        return DMABUF_ERROR_OUT_OF_MEMORY;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * DMABuf_Release
+ */
+DMABuf_Status_t
+DMABuf_Release(
+        DMABuf_Handle_t Handle)
+{
+    DMAResource_Handle_t DMAHandle =
+            Adapter_DMABuf_Handle2DMAResourceHandle(Handle);
+
+    LOG_INFO("DMABuf_Release: handle to release=%p\n",Handle.p);
+
+    if( DMAResource_Release(DMAHandle) == 0 )
+    {
+        return DMABUF_STATUS_OK;
+    }
+    else
+    {
+        return DMABUF_ERROR_INVALID_HANDLE;
+    }
+}
+
+
+/* end of file adapter_dmabuf.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_init.c
new file mode 100644
index 0000000..369d167
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_init.c
@@ -0,0 +1,113 @@
+/* adapter_driver197_init.c
+ *
+ * Adapter top level module, Security-IP-197 driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_driver197_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"             // ADAPTER_DRIVER_NAME
+
+// Adapter Initialization API
+#include "adapter_init.h"           // Adapter_*
+#include "adapter_global_init.h"    // Adapter_Global_Init/UnInit()
+#include "adapter_global_cs_init.h" // Adapter_Global_Cs_Init/UnInit()
+#include "adapter_global_drbg_init.h" // Adapter_Global_DRBG_Init/UnInit()
+
+// Logging API
+#include "log.h"            // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Init
+ */
+int
+Driver197_Init(void)
+{
+    LOG_INFO("\n\t Driver197_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Report_Build_Params();
+
+    if (!Adapter_Init())
+    {
+        return -1;
+    }
+
+    if (!Adapter_Global_Init())
+    {
+        Adapter_UnInit();
+        return -1;
+    }
+
+    if (!Adapter_Global_Cs_Init())
+    {
+        Adapter_Global_UnInit();
+        Adapter_UnInit();
+        return -1;
+    }
+
+    if (!Adapter_Global_DRBG_Init())
+    {
+        Adapter_Global_Cs_UnInit();
+        Adapter_Global_UnInit();
+        Adapter_UnInit();
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver197_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Exit
+ */
+void
+Driver197_Exit(void)
+{
+    LOG_INFO("\n\t Driver197_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Global_DRBG_UnInit();
+    Adapter_Global_Cs_UnInit();
+    Adapter_Global_UnInit();
+    Adapter_UnInit();
+
+    LOG_INFO("\n\t Driver197_Exit done \n");
+}
+
+
+#include "adapter_driver197_init_ext.h"
+
+
+/* end of file adapter_driver197_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_init.c
new file mode 100644
index 0000000..0ff732f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_init.c
@@ -0,0 +1,86 @@
+/* adapter_driver197_pec_init.c
+ *
+ * Adapter top level module, Security-IP-197 driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_driver197_pec_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"             // ADAPTER_DRIVER_NAME
+
+// Adapter Initialization API
+#include "adapter_init.h"           // Adapter_*
+
+// Logging API
+#include "log.h"            // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * DrivDriver197_PEC_Init
+ */
+int
+Driver197_PEC_Init(void)
+{
+    LOG_INFO("\n\t Driver197_PEC_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Report_Build_Params();
+
+    if (!Adapter_Init())
+    {
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver197_PEC_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_Exit
+ */
+void
+Driver197_PEC_Exit(void)
+{
+    LOG_INFO("\n\t Driver197_PEC_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_UnInit();
+
+    LOG_INFO("\n\t Driver197_PEC_Exit done \n");
+}
+
+
+#include "adapter_driver197_pec_init_ext.h"
+
+
+/* end of file adapter_driver197_pec_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_pcl_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_pcl_init.c
new file mode 100644
index 0000000..cff7787
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver197_pec_pcl_init.c
@@ -0,0 +1,86 @@
+/* adapter_driver197_pec_pcl_init.c
+ *
+ * Adapter top level module, Security-IP-197 driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_driver197_pec_pcl_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"             // ADAPTER_DRIVER_NAME
+
+// Adapter Initialization API
+#include "adapter_init.h"           // Adapter_*
+
+// Logging API
+#include "log.h"            // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * DrivDriver197_PEC_PCL_Initer197_Init
+ */
+int
+Driver197_PEC_PCL_Init(void)
+{
+    LOG_INFO("\n\t Driver197_PEC_PCL_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Report_Build_Params();
+
+    if (!Adapter_Init())
+    {
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver197_PEC_PCL_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_PEC_PCL_Exit
+ */
+void
+Driver197_PEC_PCL_Exit(void)
+{
+    LOG_INFO("\n\t Driver197_PEC_PCL_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_UnInit();
+
+    LOG_INFO("\n\t Driver197_PEC_PCL_Exit done \n");
+}
+
+
+#include "adapter_driver197_pec_pcl_init_ext.h"
+
+
+/* end of file adapter_driver197_pec_pcl_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_init.c
new file mode 100644
index 0000000..ff6b3b4
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_init.c
@@ -0,0 +1,92 @@
+/* adapter_driver97_init.c
+ *
+ * Adapter top level module, Security-IP-97 driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_driver97_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "cs_adapter.h"      // ADAPTER_DRIVER_NAME
+
+// Adapter Initialization API
+#include "adapter_init.h"   // Adapter_*
+#include "adapter_global_init.h"
+
+// Logging API
+#include "log.h"            // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * Driver97_Init
+ */
+int
+Driver97_Init(void)
+{
+    LOG_INFO("\n\t Driver97_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Report_Build_Params();
+
+    if (!Adapter_Init())
+    {
+        return -1;
+    }
+
+    if (!Adapter_Global_Init())
+    {
+        Adapter_UnInit();
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver97_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver97_Exit
+ */
+void
+Driver97_Exit(void)
+{
+    LOG_INFO("\n\t Driver97_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Global_UnInit();
+    Adapter_UnInit();
+
+    LOG_INFO("\n\t Driver97_Exit done \n");
+}
+
+#include "adapter_driver97_init_ext.h"
+
+/* end of file adapter_driver97_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_pec_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_pec_init.c
new file mode 100644
index 0000000..65b099d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_driver97_pec_init.c
@@ -0,0 +1,86 @@
+/* adapter_driver97_pec_init.c
+ *
+ * Adapter top level module, Security-IP-97 driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_driver97_pec_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"             // ADAPTER_DRIVER_NAME
+
+// Adapter Initialization API
+#include "adapter_init.h"           // Adapter_*
+
+// Logging API
+#include "log.h"            // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * DrivDriver97_PEC_Init
+ */
+int
+Driver97_PEC_Init(void)
+{
+    LOG_INFO("\n\t Driver97_PEC_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_Report_Build_Params();
+
+    if (!Adapter_Init())
+    {
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver97_PEC_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver97_PEC_Exit
+ */
+void
+Driver97_PEC_Exit(void)
+{
+    LOG_INFO("\n\t Driver97_PEC_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_DRIVER_NAME);
+
+    Adapter_UnInit();
+
+    LOG_INFO("\n\t Driver97_PEC_Exit done \n");
+}
+
+
+#include "adapter_driver97_pec_init_ext.h"
+
+
+/* end of file adapter_driver97_pec_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_cs_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_cs_init.c
new file mode 100644
index 0000000..ab91673
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_cs_init.c
@@ -0,0 +1,385 @@
+/* adapter_global_cs_init.c
+ *
+ * Initialize Global Classification Control functionality.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_global_cs_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_adapter_cs.h"
+
+// Global Control API
+#include "api_global_eip97.h"
+
+// Global Control Classification API
+#include "api_global_eip207.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework C Library API
+#include "clib.h"               // memcpy, ZEROINIT
+
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+#include "log.h"                // Log API
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static const uint32_t Global_IV_Data[4] = ADAPTER_CS_IV;
+
+
+/*----------------------------------------------------------------------------
+ * YesNo
+ *
+ * Convert boolean value to string.
+ */
+static const char *
+YesNo(
+        const bool b)
+{
+    if (b)
+        return "YES";
+    else
+        return "no";
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_Cs_StatusReport()
+ *
+ * Obtain all available global status information from the Global Classification
+ * hardware and report it.
+ */
+static void
+Adapter_Global_Cs_StatusReport(void)
+{
+    GlobalControl207_Error_t rc;
+    unsigned int i;
+    unsigned int NofCEs;
+
+    LOG_INFO("\n\t\t Adapter_Global_Cs_StatusReport \n");
+
+    LOG_CRIT("Global Classification Control Status\n");
+    GlobalControl97_Interfaces_Get(&NofCEs, NULL, NULL, NULL);
+
+    for (i = 0; i < NofCEs; i++)
+    {
+        GlobalControl207_Status_t CE_Status;
+        GlobalControl207_GlobalStats_t CE_GlobalStats;
+        GlobalControl207_Clock_t CE_Clock;
+
+        ZEROINIT(CE_Status);
+        ZEROINIT(CE_GlobalStats);
+        ZEROINIT(CE_Clock);
+
+        LOG_CRIT("Classification Engine %d status\n", i);
+
+        rc = GlobalControl207_Status_Get(i, &CE_Status);
+        if (rc != EIP207_GLOBAL_CONTROL_NO_ERROR)
+            LOG_CRIT("%s: GlobalControl207_Status_Get() failed\n", __func__);
+        else
+        {
+            if (CE_Status.ICE.fPUE_EccCorr          ||
+                CE_Status.ICE.fPUE_EccDerr          ||
+                CE_Status.ICE.fFPP_EccCorr          ||
+                CE_Status.ICE.fFPP_EccDerr          ||
+                CE_Status.ICE.fTimerOverflow        ||
+                CE_Status.OCE.fPUE_EccCorr          ||
+                CE_Status.OCE.fPUE_EccDerr          ||
+                CE_Status.OCE.fFPP_EccCorr          ||
+                CE_Status.OCE.fFPP_EccDerr          ||
+                CE_Status.OCE.fTimerOverflow        ||
+                CE_Status.FLUE.Error1 != 0          ||
+                CE_Status.FLUE.Error2 != 0          ||
+                CE_Status.FRC[0].fDMAReadError      ||
+                CE_Status.FRC[0].fDMAWriteError     ||
+                CE_Status.FRC[0].fDataEccOflo       ||
+                CE_Status.FRC[0].fDataEccErr        ||
+                CE_Status.FRC[0].fAdminEccErr       ||
+                CE_Status.TRC[0].fDMAReadError      ||
+                CE_Status.TRC[0].fDMAWriteError     ||
+                CE_Status.TRC[0].fDataEccOflo       ||
+                CE_Status.TRC[0].fDataEccErr        ||
+                CE_Status.TRC[0].fAdminEccErr       ||
+                CE_Status.ARC4RC[0].fDMAReadError   ||
+                CE_Status.ARC4RC[0].fDMAWriteError  ||
+                CE_Status.ARC4RC[0].fDataEccOflo    ||
+                CE_Status.ARC4RC[0].fDataEccErr     ||
+                CE_Status.ARC4RC[0].fAdminEccErr)
+            {
+                LOG_CRIT("%s: error(s) detected\n", __func__);
+                LOG_CRIT(
+                 "\tICE Pull-Up ECC Correctable Err:        %s\n"
+                 "\tICE Pull-Up ECC Non-Corr Err:           %s\n"
+                 "\tICE Post-Processor ECC Correctable Err: %s\n"
+                 "\tICE Post-Processor ECC Non-Corr Err:    %s\n"
+                 "\tICE Timer ovf detected:                 %s\n"
+                 "\tOCE Pull-Up ECC Correctable Err:        %s\n"
+                 "\tOCE Pull-Up ECC Non-Corr Err:           %s\n"
+                 "\tOCE Post-Processor ECC Correctable Err: %s\n"
+                 "\tOCE Post-Processor ECC Non-Corr Err:    %s\n"
+                 "\tOCE Timer ovf detected:                 %s\n"
+                 "\tFLUE Err 1:                             %s (mask=0x%08x)\n"
+                 "\tFLUE Err 2:                             %s (mask=0x%08x)\n"
+                 "\tFRC#0 DMA Read Err:                     %s\n"
+                 "\tFRC#0 DMA Write Err:                    %s\n"
+                 "\tFRC#0 Data RAM ECC Non-Corr Ovf Err:    %s\n"
+                 "\tFRC#0 Data RAM ECC Non-Corr Err:        %s\n"
+                 "\tFRC#0 Admin RAM ECC Non-Corr Err:       %s\n"
+                 "\tTRC#0 DMA Read Err:                     %s\n"
+                 "\tTRC#0 DMA Write Err:                    %s\n"
+                 "\tTRC#0 Data RAM ECC Non-Corr Ovf Err:    %s\n"
+                 "\tTRC#0 Data RAM ECC Non-Corr Err:        %s\n"
+                 "\tTRC#0 Admin RAM ECC Non-Corr Err:       %s\n"
+                 "\tARC4RC#0 DMA Read Err:                  %s\n"
+                 "\tARC4RC#0 DMA Write Err:                 %s\n"
+                 "\tARC4RC#0 Data RAM ECC Non-Corr Ovf Err: %s\n"
+                 "\tARC4RC#0 Data RAM ECC Non-Corr Err:     %s\n"
+                 "\tARC4RC#0 Admin RAM ECC Non-Corr Err:    %s\n\n",
+                 YesNo(CE_Status.ICE.fPUE_EccCorr),
+                 YesNo(CE_Status.ICE.fPUE_EccDerr),
+                 YesNo(CE_Status.ICE.fFPP_EccCorr),
+                 YesNo(CE_Status.ICE.fFPP_EccDerr),
+                 YesNo(CE_Status.ICE.fTimerOverflow),
+                 YesNo(CE_Status.OCE.fPUE_EccCorr),
+                 YesNo(CE_Status.OCE.fPUE_EccDerr),
+                 YesNo(CE_Status.OCE.fFPP_EccCorr),
+                 YesNo(CE_Status.OCE.fFPP_EccDerr),
+                 YesNo(CE_Status.OCE.fTimerOverflow),
+                 YesNo(CE_Status.FLUE.Error1 != 0),
+                 CE_Status.FLUE.Error1,
+                 YesNo(CE_Status.FLUE.Error2 != 0),
+                 CE_Status.FLUE.Error2,
+                 YesNo(CE_Status.FRC[0].fDMAReadError),
+                 YesNo(CE_Status.FRC[0].fDMAWriteError),
+                 YesNo(CE_Status.FRC[0].fDataEccOflo),
+                 YesNo(CE_Status.FRC[0].fDataEccErr),
+                 YesNo(CE_Status.FRC[0].fAdminEccErr),
+                 YesNo(CE_Status.TRC[0].fDMAReadError),
+                 YesNo(CE_Status.TRC[0].fDMAWriteError),
+                 YesNo(CE_Status.TRC[0].fDataEccOflo),
+                 YesNo(CE_Status.TRC[0].fDataEccErr),
+                 YesNo(CE_Status.TRC[0].fAdminEccErr),
+                 YesNo(CE_Status.ARC4RC[0].fDMAReadError),
+                 YesNo(CE_Status.ARC4RC[0].fDMAWriteError),
+                 YesNo(CE_Status.ARC4RC[0].fDataEccOflo),
+                 YesNo(CE_Status.ARC4RC[0].fDataEccErr),
+                 YesNo(CE_Status.ARC4RC[0].fAdminEccErr));
+            }
+            else
+                LOG_CRIT("%s: all OK\n", __func__);
+            if (CE_Status.FRCStats[0].PrefetchExec ||
+                CE_Status.FRCStats[0].PrefetchBlock ||
+                CE_Status.FRCStats[0].PrefetchDMA ||
+                CE_Status.FRCStats[0].SelectOps ||
+                CE_Status.FRCStats[0].SelectDMA ||
+                CE_Status.FRCStats[0].IntDMAWrite ||
+                CE_Status.FRCStats[0].ExtDMAWrite ||
+                CE_Status.FRCStats[0].InvalidateOps)
+            {
+                LOG_CRIT("FRC statistics:\n"
+                         "\tPrefetches executed: %u\n"
+                         "\tPrefetches blocked:  %u\n"
+                         "\tPrefetches with DMA: %u\n"
+                         "\tSelect ops:          %u\n"
+                         "\tSelect ops with DMA: %u\n"
+                         "\tInternal DMA writes: %u\n"
+                         "\tExternal DMA writes: %u\n"
+                         "\tInvalidate ops:      %u\n"
+                         "\tDMA err flags        0x%x\n"
+                         "\tRead DMA errs:       %u\n"
+                         "\tWrite DMA errs:      %u\n"
+                         "\tECC invalidates:     %u\n"
+                         "\tECC Data RAM Corr:   %u\n"
+                         "\tECC Admin RAM Corr:  %u\n",
+                         (uint32_t)CE_Status.FRCStats[0].PrefetchExec,
+                         (uint32_t)CE_Status.FRCStats[0].PrefetchBlock,
+                         (uint32_t)CE_Status.FRCStats[0].PrefetchDMA,
+                         (uint32_t)CE_Status.FRCStats[0].SelectOps,
+                         (uint32_t)CE_Status.FRCStats[0].SelectDMA,
+                         (uint32_t)CE_Status.FRCStats[0].IntDMAWrite,
+                         (uint32_t)CE_Status.FRCStats[0].ExtDMAWrite,
+                         (uint32_t)CE_Status.FRCStats[0].InvalidateOps,
+                         (uint32_t)CE_Status.FRCStats[0].ReadDMAErrFlags,
+                         (uint32_t)CE_Status.FRCStats[0].ReadDMAErrors,
+                         (uint32_t)CE_Status.FRCStats[0].WriteDMAErrors,
+                         (uint32_t)CE_Status.FRCStats[0].InvalidateECC,
+                         (uint32_t)CE_Status.FRCStats[0].DataECCCorr,
+                         (uint32_t)CE_Status.FRCStats[0].AdminECCCorr);
+            }
+            if (CE_Status.TRCStats[0].PrefetchExec ||
+                CE_Status.TRCStats[0].PrefetchBlock ||
+                CE_Status.TRCStats[0].PrefetchDMA ||
+                CE_Status.TRCStats[0].SelectOps ||
+                CE_Status.TRCStats[0].SelectDMA ||
+                CE_Status.TRCStats[0].IntDMAWrite ||
+                CE_Status.TRCStats[0].ExtDMAWrite ||
+                CE_Status.TRCStats[0].InvalidateOps)
+            {
+                LOG_CRIT("TRC statistics:\n"
+                         "\tPrefetches executed: %u\n"
+                         "\tPrefetches blocked:  %u\n"
+                         "\tPrefetches with DMA: %u\n"
+                         "\tSelect ops:          %u\n"
+                         "\tSelect ops with DMA: %u\n"
+                         "\tInternal DMA writes: %u\n"
+                         "\tExternal DMA writes: %u\n"
+                         "\tInvalidate ops:      %u\n"
+                         "\tDMA err flags        0x%x\n"
+                         "\tRead DMA errs:       %u\n"
+                         "\tWrite DMA errs:      %u\n"
+                         "\tECC invalidates:     %u\n"
+                         "\tECC Data RAM Corr:   %u\n"
+                         "\tECC Admin RAM Corr:  %u\n",
+                         (uint32_t)CE_Status.TRCStats[0].PrefetchExec,
+                         (uint32_t)CE_Status.TRCStats[0].PrefetchBlock,
+                         (uint32_t)CE_Status.TRCStats[0].PrefetchDMA,
+                         (uint32_t)CE_Status.TRCStats[0].SelectOps,
+                         (uint32_t)CE_Status.TRCStats[0].SelectDMA,
+                         (uint32_t)CE_Status.TRCStats[0].IntDMAWrite,
+                         (uint32_t)CE_Status.TRCStats[0].ExtDMAWrite,
+                         (uint32_t)CE_Status.TRCStats[0].InvalidateOps,
+                         (uint32_t)CE_Status.TRCStats[0].ReadDMAErrFlags,
+                         (uint32_t)CE_Status.TRCStats[0].ReadDMAErrors,
+                         (uint32_t)CE_Status.TRCStats[0].WriteDMAErrors,
+                         (uint32_t)CE_Status.TRCStats[0].InvalidateECC,
+                         (uint32_t)CE_Status.TRCStats[0].DataECCCorr,
+                         (uint32_t)CE_Status.TRCStats[0].AdminECCCorr);
+            }
+        }
+
+        rc = GlobalControl207_GlobalStats_Get(i, &CE_GlobalStats);
+        if (rc != EIP207_GLOBAL_CONTROL_NO_ERROR)
+            LOG_CRIT("Adapter_Global_Cs_StatusReport: "
+                     "GlobalControl207_GlobalStats_Get() failed\n");
+        else
+            LOG_CRIT(
+                 "\tICE Dropped Packets Counter (low 32-bits):     0x%08x\n"
+                 "\tICE Dropped Packets Counter (high 32-bits):    0x%08x\n"
+                 "\tICE Inbound Packets Counter:                   0x%08x\n"
+                 "\tICE Outbound Packets Counter:                  0x%08x\n"
+                 "\tICE Inbound Octets Counter (low 32-bits):      0x%08x\n"
+                 "\tICE Inbound Octets Counter (high 32-bits):     0x%08x\n"
+                 "\tICE Outbound Octets Counter (low 32-bits):     0x%08x\n"
+                 "\tICE Outbound Octets Counter (high 32-bits):    0x%08x\n"
+                 "\tOCE Dropped Packets Counter (low 32-bits):     0x%08x\n"
+                 "\tOCE Dropped Packets Counter (high 32-bits):    0x%08x\n\n",
+                 CE_GlobalStats.ICE.DroppedPacketsCounter.Value64_Lo,
+                 CE_GlobalStats.ICE.DroppedPacketsCounter.Value64_Hi,
+                 CE_GlobalStats.ICE.InboundPacketsCounter,
+                 CE_GlobalStats.ICE.OutboundPacketCounter,
+                 CE_GlobalStats.ICE.InboundOctetsCounter.Value64_Lo,
+                 CE_GlobalStats.ICE.InboundOctetsCounter.Value64_Hi,
+                 CE_GlobalStats.ICE.OutboundOctetsCounter.Value64_Lo,
+                 CE_GlobalStats.ICE.OutboundOctetsCounter.Value64_Hi,
+                 CE_GlobalStats.OCE.DroppedPacketsCounter.Value64_Lo,
+                 CE_GlobalStats.OCE.DroppedPacketsCounter.Value64_Hi);
+
+        rc = GlobalControl207_ClockCount_Get(i, &CE_Clock);
+        if (rc != EIP207_GLOBAL_CONTROL_NO_ERROR)
+            LOG_CRIT("Adapter_Global_Cs_StatusReport: "
+                     "GlobalControl207_ClockCount_Get() failed\n");
+        else
+            LOG_CRIT(
+                 "\tICE Clock Count (low 32-bits):   0x%08x\n"
+                 "\tICE Clock Count (high 32-bits):  0x%08x\n"
+                 "\tOCE Clock Count (low 32-bits):   0x%08x\n"
+                 "\tOCE Clock Count (high 32-bits):  0x%08x\n\n",
+                 CE_Clock.ICE.Value64_Lo,
+                 CE_Clock.ICE.Value64_Hi,
+                 CE_Clock.OCE.Value64_Lo,
+                 CE_Clock.OCE.Value64_Hi);
+    } // for
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_Cs_Init()
+ *
+ */
+bool
+Adapter_Global_Cs_Init(void)
+{
+    GlobalControl207_Error_t rc;
+    GlobalControl207_Capabilities_t Capabilities;
+    GlobalControl207_IV_t Data;
+
+    LOG_INFO("\n\t\t Adapter_Global_Cs_Init \n");
+
+    Data.IV[0] = Global_IV_Data[0];
+    Data.IV[1] = Global_IV_Data[1];
+    Data.IV[2] = Global_IV_Data[2];
+    Data.IV[3] = Global_IV_Data[3];
+
+    // Request the classification firmware download during the initialization
+    rc = GlobalControl207_Init(true, &Data);
+    if (rc != EIP207_GLOBAL_CONTROL_NO_ERROR)
+    {
+        LOG_CRIT("Adaptar_Global_Init: Classification initialization failed\n");
+        return false;
+    }
+
+    Capabilities.szTextDescription[0] = 0;
+
+    GlobalControl207_Capabilities_Get(&Capabilities);
+
+    LOG_CRIT("Global Classification capabilities: %s\n",
+             Capabilities.szTextDescription);
+
+    Adapter_Global_Cs_StatusReport();
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_Cs_UnInit()
+ *
+ */
+void
+Adapter_Global_Cs_UnInit(void)
+{
+    LOG_INFO("\n\t\t Adapter_Global_Cs_UnInit \n");
+
+    Adapter_Global_Cs_StatusReport();
+
+    GlobalControl207_UnInit();
+}
+
+
+/* end of file adapter_global_cs_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_drbg_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_drbg_init.c
new file mode 100644
index 0000000..a210faa
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_drbg_init.c
@@ -0,0 +1,209 @@
+/* adapter_global drbg_init.c
+ *
+ * Initialize Global DRBG Control functionality.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_global_drbg_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_adapter_global.h"
+
+// Global Control DRBG API
+#include "api_global_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework C Library API
+#include "clib.h"               // memcpy, ZEROINIT
+
+// Log API
+#include "log.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static bool fDRBGPresent;
+
+#ifdef MODULE
+#include <linux/random.h>
+#define Global_DRBG_Entropy_Get(p) get_random_bytes(p, 48);
+#else
+#include <stdio.h>
+/*----------------------------------------------------------------------------
+ * Global_DRBG_Entropy_Get
+ *
+ * Get 48 bytes of entropy to initialize/reseed DRBG.
+ */
+static void
+Global_DRBG_Entropy_Get(
+    uint8_t * Key_p)
+{
+    FILE *rng = fopen("/dev/urandom","rb");
+    if (rng==NULL)
+    {
+        LOG_CRIT("/dev/urandom not available\n");
+        return;
+    }
+    if (fread(Key_p, 1, 48, rng) < 48)
+    {
+        LOG_CRIT("random data not read\n");
+        return;
+    }
+    Log_HexDump("Entropy",0,Key_p,48);
+
+    fclose(rng);
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * BoolToString()
+ *
+ * Convert boolean value to string.
+ */
+static const char *
+BoolToString(
+        const bool b)
+{
+    if (b)
+        return "true";
+    else
+        return "false";
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_DRBG_StatusReport()
+ *
+ * Obtain all available global status information from the Global DRBG
+ * hardware and report it.
+ */
+void
+Adapter_Global_DRBG_StatusReport(void)
+{
+    GlobalControl74_Error_t Rc;
+    GlobalControl74_Status_t Status;
+
+    LOG_INFO("DA_GC: Global_DRBG_StatusReport \n");
+
+    LOG_CRIT("DA_GC: Global DRBG Status\n");
+    Rc = GlobalControl74_Status_Get(&Status);
+    if (Rc != GLOBAL_CONTROL_EIP74_NO_ERROR)
+    {
+        LOG_CRIT("EIP74 status get error\n");
+        return;
+    }
+    Log_FormattedMessage(
+        "EIP 74 status: GenBlockCount=%u StuckOut=%s\n"
+        "\t\tNotInitialized=%s ReseedErr=%s ReseedWarn=%s\n"
+        "\t\tInstantiated=%s AvailableCount=%u\n",
+        Status.GenerateBlockCount,
+        BoolToString(Status.fStuckOut),
+        BoolToString(Status.fNotInitialized),
+        BoolToString(Status.fReseedError),
+        BoolToString(Status.fReseedWarning),
+        BoolToString(Status.fInstantiated),
+        Status.AvailableCount);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_DRBG_Init()
+ *
+ */
+bool
+Adapter_Global_DRBG_Init(void)
+{
+    GlobalControl74_Error_t rc;
+    GlobalControl74_Capabilities_t Capabilities;
+    GlobalControl74_Configuration_t Configuration;
+    uint8_t Entropy[48];
+
+    LOG_INFO("DA_GC: Global_DRBG_Init \n");
+
+    ZEROINIT(Configuration);
+    Configuration.fStuckOut = true;
+
+    Global_DRBG_Entropy_Get(Entropy);
+
+    rc = GlobalControl74_Init(&Configuration, Entropy);
+    if (rc == GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED)
+    {
+        LOG_CRIT("EIP74 not present\n");
+        return true;
+    }
+    if (rc == GLOBAL_CONTROL_EIP74_NO_ERROR)
+    {
+        fDRBGPresent = true;
+        Log_FormattedMessage("EIP74 initialized OK\n");
+    }
+    else
+    {
+        LOG_CRIT("EIP74 initialization error\n");
+    }
+
+    Capabilities.szTextDescription[0] = 0;
+
+    GlobalControl74_Capabilities_Get(&Capabilities);
+
+    LOG_CRIT("DA_GC: Global DRBG capabilities: %s\n",
+             Capabilities.szTextDescription);
+
+    Adapter_Global_DRBG_StatusReport();
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_DRBG_UnInit()
+ *
+ */
+void
+Adapter_Global_DRBG_UnInit(void)
+{
+    LOG_INFO("\n\t\t Adapter_Global_DRBG_UnInit \n");
+
+    if (fDRBGPresent)
+    {
+        Adapter_Global_DRBG_StatusReport();
+
+        GlobalControl74_UnInit();
+    }
+}
+
+
+/* end of file adapter_global_drbg_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver197_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver197_init.c
new file mode 100644
index 0000000..158dc38
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver197_init.c
@@ -0,0 +1,87 @@
+/* adapter_global_driver197_init.c
+ *
+ * Adapter top level module,
+ * Security-IP-197 global control driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_global_driver197_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "c_adapter_global.h"             // ADAPTER_GLOBAL_DRIVER_NAME
+
+// Adapter Initialization API - for global only tjc
+#include "adapter_global_control_init.h"  // Adapter_* for global only
+
+// Logging API
+#include "log.h"                          // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Global_Init
+ */
+int
+Driver197_Global_Init(void)
+{
+    LOG_INFO("\n\t Driver197_Global_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_GLOBAL_DRIVER_NAME);
+
+    Adapter_Global_Control_Report_Build_Params();
+
+    if (!Adapter_Global_Control_Init())
+    {
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver197_Global_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver197_Global_Exit
+ */
+void
+Driver197_Global_Exit(void)
+{
+    LOG_INFO("\n\t Driver197_Global_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_GLOBAL_DRIVER_NAME);
+
+    Adapter_Global_Control_UnInit();
+
+    LOG_INFO("\n\t Driver197_Globt done \n");
+}
+
+
+#include "adapter_driver197_global_init_ext.h"
+
+
+/* end of file adapter_global_driver197_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver97_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver97_init.c
new file mode 100644
index 0000000..bb38914
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_driver97_init.c
@@ -0,0 +1,87 @@
+/* adapter_global_driver97_init.c
+ *
+ * Adapter top level module,
+ * Security-IP-97 global control driver's entry point.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_global_driver97_init.h"    // Driver Init API
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "c_adapter_global.h"             // ADAPTER_GLOBAL_DRIVER_NAME
+
+// Adapter Initialization API - for global only tjc
+#include "adapter_global_control_init.h"  // Adapter_* for global only
+
+// Logging API
+#include "log.h"                          // LOG_INFO
+
+
+/*----------------------------------------------------------------------------
+ * Driver97_Global_Init
+ */
+int
+Driver97_Global_Init(void)
+{
+    LOG_INFO("\n\t Driver97_Global_Init \n");
+
+    LOG_INFO("%s driver: initializing\n", ADAPTER_GLOBAL_DRIVER_NAME);
+
+    Adapter_Global_Control_Report_Build_Params();
+
+    if (!Adapter_Global_Control_Init())
+    {
+        return -1;
+    }
+
+    LOG_INFO("\n\t Driver97_Global_Init done \n");
+
+    return 0;   // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Driver97_Global_Exit
+ */
+void
+Driver97_Global_Exit(void)
+{
+    LOG_INFO("\n\t Driver97_Global_Exit \n");
+
+    LOG_INFO("%s driver: exit\n", ADAPTER_GLOBAL_DRIVER_NAME);
+
+    Adapter_Global_Control_UnInit();
+
+    LOG_INFO("\n\t Driver97_Global_Exit done \n");
+}
+
+
+#include "adapter_driver97_global_init_ext.h"
+
+
+/* end of file adapter_global_driver97_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip207.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip207.c
new file mode 100644
index 0000000..11b8139
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip207.c
@@ -0,0 +1,740 @@
+/* adapter_global_eip207.c
+ *
+ * Security-IP-207 Global Control Adapter
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Classification (EIP-207) Global Control Initialization API
+#include "api_global_eip207.h"
+
+// Classification (EIP-207) Global Control Status API
+#include "api_global_status_eip207.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_adapter_cs.h"
+
+#ifndef GLOBALCONTROL_BUILD
+#include "adapter_rc_eip207.h"  // Record Cache EIP-207 interface to pass
+                                // config params from Global Control
+#endif
+
+// Global Control API
+#include "api_global_eip97.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"          // uint8_t, uint32_t, bool
+
+// Driver Framework C Library API
+#include "clib.h"                // memcpy, ZEROINIT
+
+// EIP-207 Driver Library Global Control API
+#include "eip207_global_init.h"  // Init/Uninit/Status/FW download
+
+// EIP-207 Driver Library Global Control API: Configuration
+#include "eip207_global_config.h" // EIP207_Global_MetaData_Configure
+
+#include "device_types.h"        // Device_Handle_t
+#include "device_mgmt.h"         // Device_find
+
+// Logging API
+#include "log.h"                 // Log_*, LOG_*
+
+// Firmware load API.
+#include "adapter_firmware.h"
+#include "firmware_eip207_api_dwld.h"
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+// EIP97_Supported_Funcs_Get()
+#include "eip97_global_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/* Support legacy firmware packages without name parameters in download API */
+#ifndef FIRMWARE_EIP207_IPUE_NAME
+#define FIRMWARE_EIP207_IPUE_NAME "firmware_eip207_ipue.bin"
+#define FIRMWARE_EIP207_IFPP_NAME "firmware_eip207_ifpp.bin"
+#endif
+#ifndef FIRMWARE_EIP207_OPUE_NAME
+#define FIRMWARE_EIP207_OPUE_NAME "firmware_eip207_opue.bin"
+#define FIRMWARE_EIP207_OFPP_NAME "firmware_eip207_ofpp.bin"
+#endif
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static EIP207_Global_IOArea_t Global_IOArea;
+static bool Global_IsInitialized;
+
+// Cached values during initialization will be used for RPM device resume
+static EIP207_Global_CacheConfig_t RC_Conf;
+static EIP207_Global_FLUEConfig_t FLUE_Conf;
+
+static const  GlobalControl207_Capabilities_t Global_CapabilitiesString =
+{
+    "EIP-207 v_._p_  #cache sets=__ #lookup tables=__" // szTextDescription
+};
+
+
+/*----------------------------------------------------------------------------
+ * YesNo
+ */
+static const char *
+YesNo(
+        const bool b)
+{
+    if (b)
+        return "Yes";
+    else
+        return "No";
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207Lib_Init
+ *
+ */
+static int
+GlobalControl207Lib_Init(void)
+{
+    EIP207_Global_Error_t rc;
+    unsigned int i;
+
+    LOG_INFO("\n\t\t\t\t EIP207_Global_Init \n");
+
+    rc = EIP207_Global_Init(&Global_IOArea,
+                            Device_Find(ADAPTER_CS_GLOBAL_DEVICE_NAME),
+                            &RC_Conf,
+                            &FLUE_Conf);
+
+    for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+    {
+        Log_FormattedMessage("GlobalControl_EIP207_Init cache set %d:\n"
+                             "\t\tFRC  AdminWords=%5d DataWords=%5d\n"
+                             "\t\tTRC  AdminWords=%5d DataWords=%5d\n"
+                             "\t\tARC4 AdminWords=%5d DataWords=%5d\n",
+                             i,
+                             RC_Conf.FRC[i].AdminWordCount,
+                             RC_Conf.FRC[i].DataWordCount,
+                             RC_Conf.TRC[i].AdminWordCount,
+                             RC_Conf.TRC[i].DataWordCount,
+                             RC_Conf.ARC4[i].AdminWordCount,
+                             RC_Conf.ARC4[i].DataWordCount);
+    }
+
+    if (rc != EIP207_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP207_Global_Init() returned error %d\n", __func__, rc);
+        return -1; // error
+    }
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207Lib_Firmware_Load
+ *
+ */
+static int
+GlobalControl207Lib_Firmware_Load(bool fVerbose)
+{
+    Adapter_Firmware_t IPUE_Handle, IFPP_Handle,OPUE_Handle, OFPP_Handle;
+    EIP207_Firmware_t IPUE_Firmware, IFPP_Firmware;
+    EIP207_Firmware_t OPUE_Firmware, OFPP_Firmware;
+    EIP207_Global_Error_t rc;
+
+    ZEROINIT(IPUE_Firmware);
+    ZEROINIT(IFPP_Firmware);
+    ZEROINIT(OPUE_Firmware);
+    ZEROINIT(OFPP_Firmware);
+
+#ifdef FIRMWARE_EIP207_VERSION_MAJOR
+    // If version numbers are provided, then fill them in, so they
+    // will be checked against the actual firmware, else leave them
+    // at zero.
+    IPUE_Firmware.Major = FIRMWARE_EIP207_VERSION_MAJOR;
+    IPUE_Firmware.Minor = FIRMWARE_EIP207_VERSION_MINOR;
+    IPUE_Firmware.PatchLevel = FIRMWARE_EIP207_VERSION_PATCH;
+    IFPP_Firmware.Major = FIRMWARE_EIP207_VERSION_MAJOR;
+    IFPP_Firmware.Minor = FIRMWARE_EIP207_VERSION_MINOR;
+    IFPP_Firmware.PatchLevel = FIRMWARE_EIP207_VERSION_PATCH;
+    OPUE_Firmware.Major = FIRMWARE_EIP207_VERSION_MAJOR;
+    OPUE_Firmware.Minor = FIRMWARE_EIP207_VERSION_MINOR;
+    OPUE_Firmware.PatchLevel = FIRMWARE_EIP207_VERSION_PATCH;
+    OFPP_Firmware.Major = FIRMWARE_EIP207_VERSION_MAJOR;
+    OFPP_Firmware.Minor = FIRMWARE_EIP207_VERSION_MINOR;
+    OFPP_Firmware.PatchLevel = FIRMWARE_EIP207_VERSION_PATCH;
+#endif
+    IPUE_Handle = Adapter_Firmware_Acquire(FIRMWARE_EIP207_IPUE_NAME,
+                                           &IPUE_Firmware.Image_p,
+                                           &IPUE_Firmware.ImageWordCount);
+    IFPP_Handle = Adapter_Firmware_Acquire(FIRMWARE_EIP207_IFPP_NAME,
+                                           &IFPP_Firmware.Image_p,
+                                           &IFPP_Firmware.ImageWordCount);
+    if ((EIP97_SupportedFuncs_Get() & BIT_1) != 0)
+    {
+        OPUE_Handle = Adapter_Firmware_Acquire(FIRMWARE_EIP207_OPUE_NAME,
+                                               &OPUE_Firmware.Image_p,
+                                               &OPUE_Firmware.ImageWordCount);
+        OFPP_Handle = Adapter_Firmware_Acquire(FIRMWARE_EIP207_OFPP_NAME,
+                                               &OFPP_Firmware.Image_p,
+                                               &OFPP_Firmware.ImageWordCount);
+    }
+    else
+    {
+        OPUE_Handle = Adapter_Firmware_NULL;
+        OFPP_Handle = Adapter_Firmware_NULL;
+    }
+
+    LOG_INFO("\n\t\t\t\t EIP207_Global_Firmware_Load \n");
+
+    rc = EIP207_Global_Firmware_Load(&Global_IOArea,
+                                     ADAPTER_CS_TIMER_PRESCALER,
+                                     &IPUE_Firmware,
+                                     &IFPP_Firmware,
+                                     &OPUE_Firmware,
+                                     &OFPP_Firmware);
+    Adapter_Firmware_Release(IPUE_Handle);
+    Adapter_Firmware_Release(IFPP_Handle);
+    Adapter_Firmware_Release(OPUE_Handle);
+    Adapter_Firmware_Release(OFPP_Handle);
+    if (rc != EIP207_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("GlobalControl207_Init: "
+                 "EIP207_Global_Firmware_Load() failed\n");
+        return -3; // error
+    }
+    else if (fVerbose)
+    {
+        LOG_CRIT("GlobalControl207_Init: firmware "
+                 "downloaded successfully\n");
+
+        LOG_CRIT("\tIPUE firmware v%d.%d.%d, image byte count %d\n",
+                 IPUE_Firmware.Major,
+                 IPUE_Firmware.Minor,
+                 IPUE_Firmware.PatchLevel,
+                 (int)(IPUE_Firmware.ImageWordCount * sizeof(uint32_t)));
+
+        LOG_CRIT("\tIFPP firmware v%d.%d.%d, image byte count %d\n\n",
+                 IFPP_Firmware.Major,
+                     IFPP_Firmware.Minor,
+                 IFPP_Firmware.PatchLevel,
+                 (int)(IFPP_Firmware.ImageWordCount * sizeof(uint32_t)));
+
+        LOG_CRIT("\tOPUE firmware v%d.%d.%d, image byte count %d\n",
+                 OPUE_Firmware.Major,
+                 OPUE_Firmware.Minor,
+                 OPUE_Firmware.PatchLevel,
+                     (int)(OPUE_Firmware.ImageWordCount * sizeof(uint32_t)));
+
+        LOG_CRIT("\tOFPP firmware v%d.%d.%d, image byte count %d\n\n",
+                 OFPP_Firmware.Major,
+                 OFPP_Firmware.Minor,
+                 OFPP_Firmware.PatchLevel,
+                 (int)(OFPP_Firmware.ImageWordCount * sizeof(uint32_t)));
+    }
+    return 0;
+}
+
+#ifdef ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID
+/*----------------------------------------------------------------------------
+ * GlobalControl207Lib_Resume
+ *
+ */
+static int
+GlobalControl207Lib_Resume(void * p)
+{
+    EIP207_Global_Error_t rc;
+    EIP207_Firmware_t IPUE_Firmware, IFPP_Firmware;
+    EIP207_Firmware_t OPUE_Firmware, OFPP_Firmware;
+
+    IDENTIFIER_NOT_USED(p);
+
+    if (GlobalControl207Lib_Init() != 0)
+        return -1; // error
+
+    if (GlobalControl207Lib_Firmware_Load(false) != 0)
+        return -2; // error
+
+    return 0; // success
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Capabilities_Get
+ */
+void
+GlobalControl207_Capabilities_Get(
+        GlobalControl207_Capabilities_t * const Capabilities_p)
+{
+    uint8_t Versions[7];
+
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    memcpy(Capabilities_p, &Global_CapabilitiesString,
+           sizeof(Global_CapabilitiesString));
+
+    {
+        EIP207_Global_Error_t rc;
+        EIP207_Global_Capabilities_t Capabilities;
+
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                RPM_FLAG_SYNC) != RPM_SUCCESS)
+            return;
+
+        LOG_INFO("\n\t\t\t\t EIP207_Global_HWRevision_Get \n");
+
+        rc = EIP207_Global_HWRevision_Get(&Global_IOArea, &Capabilities);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                       RPM_FLAG_ASYNC);
+
+        if (rc != EIP207_GLOBAL_NO_ERROR)
+        {
+            LOG_CRIT("GlobalControl207_Capabilities_Get: "
+                     "EIP207_Global_HWRevision_Get() failed\n");
+            return;
+        }
+
+        // Show those capabilities not propagated to higher layer.
+        LOG_CRIT("EIP-207 capabilities\n");
+        LOG_CRIT("\tLookup cached:            %s\n"
+                 "\tFRC combined with TRC:    %s\n"
+                 "\tARC4RC present:           %s\n"
+                 "\tFRC combined with ARC4RC: %s\n"
+                 "\tTRC combined with ARC4RC: %s\n"
+                 "\tFRC clients:              %d\n"
+                 "\tTRC clients:              %d\n"
+                 "\tARC4RC clients:           %d\n"
+                 "\tLookup clients:           %d\n\n",
+                 YesNo(Capabilities.EIP207_Options.fLookupCached),
+                 YesNo(Capabilities.EIP207_Options.fCombinedFRC_TRC),
+                 YesNo(Capabilities.EIP207_Options.fARC4Present),
+                 YesNo(Capabilities.EIP207_Options.fCombinedFRC_ARC4),
+                 YesNo(Capabilities.EIP207_Options.fCombinedTRC_ARC4),
+                 Capabilities.EIP207_Options.NofFRC_Clients,
+                 Capabilities.EIP207_Options.NofTRC_Clients,
+                 Capabilities.EIP207_Options.NofARC4_Clients,
+                 Capabilities.EIP207_Options.NofLookupClients);
+
+        Versions[0] = Capabilities.EIP207_Version.MajHWRevision;
+        Versions[1] = Capabilities.EIP207_Version.MinHWRevision;
+        Versions[2] = Capabilities.EIP207_Version.HWPatchLevel;
+
+        Versions[3] = Capabilities.EIP207_Options.NofCacheSets / 10;
+        Versions[4] = Capabilities.EIP207_Options.NofCacheSets % 10;
+
+        Versions[5] = Capabilities.EIP207_Options.NofLookupTables / 10;
+        Versions[6] = Capabilities.EIP207_Options.NofLookupTables % 10;
+    }
+
+    {
+        char * p = Capabilities_p->szTextDescription;
+        int VerIndex = 0;
+        int i = 0;
+
+        while(p[i])
+        {
+            if (p[i] == '_')
+            {
+                if (Versions[VerIndex] > 9)
+                    p[i] = '?';
+                else
+                    p[i] = '0' + Versions[VerIndex++];
+
+                if (VerIndex >= 7)
+                    break;
+            }
+
+            i++;
+        }
+    }
+
+    return;
+}
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Init
+ */
+GlobalControl207_Error_t
+GlobalControl207_Init(
+        const bool fLoadFirmware,
+        const GlobalControl207_IV_t * const IV_p)
+{
+    unsigned int i;
+    GlobalControl207_Error_t GC207_Rc = EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+    EIP207_Global_Error_t rc;
+    Device_Handle_t Device;
+    unsigned int NofCEs,NofRings,NofLAInterfaces,NofInlineInterfaces;
+
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    if (Global_IsInitialized)
+    {
+        LOG_CRIT("GlobalControl207_Init: called while already initialized\n");
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_USE_ORDER;
+    }
+
+    Device = Device_Find(ADAPTER_CS_GLOBAL_DEVICE_NAME);
+    if (Device == NULL)
+    {
+        LOG_CRIT("GlobalControl207_Init: Could not find device\n");
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+    }
+
+    ZEROINIT(RC_Conf);
+    ZEROINIT(FLUE_Conf);
+
+    // Record Caches initialization parameters
+    for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+    {
+        RC_Conf.FRC[i].fEnable = (ADAPTER_CS_FRC_ENABLED != 0);
+        RC_Conf.FRC[i].fNonBlock = false;
+        RC_Conf.FRC[i].BlockClockCount = ADAPTER_CS_RC_BLOCK_CLOCK_COUNT;
+        RC_Conf.FRC[i].RecBaseAddr.Value64_Lo = 0;
+        RC_Conf.FRC[i].RecBaseAddr.Value64_Hi = 0;
+
+        RC_Conf.TRC[i].fEnable = (ADAPTER_CS_TRC_ENABLED != 0);
+        RC_Conf.TRC[i].fNonBlock = false;
+        RC_Conf.TRC[i].BlockClockCount = ADAPTER_CS_RC_BLOCK_CLOCK_COUNT;
+        RC_Conf.TRC[i].RecBaseAddr.Value64_Lo = 0;
+        RC_Conf.TRC[i].RecBaseAddr.Value64_Hi = 0;
+
+        RC_Conf.ARC4[i].fEnable = (ADAPTER_CS_ARC4RC_ENABLED != 0);
+        RC_Conf.ARC4[i].fNonBlock = false;
+        RC_Conf.ARC4[i].BlockClockCount = ADAPTER_CS_RC_BLOCK_CLOCK_COUNT;
+        RC_Conf.ARC4[i].RecBaseAddr.Value64_Lo = 0;
+        RC_Conf.ARC4[i].RecBaseAddr.Value64_Hi = 0;
+    }
+
+    // Flow Look-Up Engine initialization parameters
+    FLUE_Conf.CacheChain = ADAPTER_CS_FLUE_CACHE_CHAIN;
+    FLUE_Conf.fDelayMemXS = (ADAPTER_CS_FLUE_MEMXS_DELAY != 0);
+    FLUE_Conf.IV.IV_Word32[0] = IV_p->IV[0];
+    FLUE_Conf.IV.IV_Word32[1] = IV_p->IV[1];
+    FLUE_Conf.IV.IV_Word32[2] = IV_p->IV[2];
+    FLUE_Conf.IV.IV_Word32[3] = IV_p->IV[3];
+
+    // Hash table initialization parameters
+    FLUE_Conf.HashTablesCount = ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE;
+    for (i = 0; i < FLUE_Conf.HashTablesCount; i++)
+    {
+        FLUE_Conf.HashTable[i].fLookupCached =
+                                    (ADAPTER_CS_FLUE_LOOKUP_CACHED != 0);
+        FLUE_Conf.HashTable[i].fPrefetchXform =
+                                    (ADAPTER_CS_FLUE_PREFETCH_XFORM != 0);
+        FLUE_Conf.HashTable[i].fPrefetchARC4State =
+                                    (ADAPTER_CS_FLUE_PREFETCH_ARC4 != 0);
+    }
+
+    GlobalControl97_Interfaces_Get(&NofCEs, &NofRings, &NofLAInterfaces, &NofInlineInterfaces);
+    LOG_CRIT("GlobalControl_EIP207_Init:\n"
+             "Number of Rings: %u, LA Interfaces: %u, Inline interfaces: %u\n",
+             NofRings,NofLAInterfaces,NofInlineInterfaces);
+
+    FLUE_Conf.InterfacesCount = NofRings + NofLAInterfaces +
+                                                    NofInlineInterfaces;
+    if (FLUE_Conf.InterfacesCount == 0)
+    {
+        LOG_CRIT("GlobalControl207_Init: Device not initialized\n");
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+    }
+
+    for (i = 0; i < FLUE_Conf.InterfacesCount; i++)
+        FLUE_Conf.InterfaceIndex[i] = 0;
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                    NULL, // Suspend callback not used
+                                    GlobalControl207Lib_Resume) != RPM_SUCCESS)
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    if (GlobalControl207Lib_Init() != 0)
+        goto exit; // error
+
+    // Configure the Record Cache functionality at the Ring Control
+    {
+        EIP207_Global_Capabilities_t Capabilities;
+
+        LOG_INFO("\n\t\t\t\t EIP207_Global_HWRevision_Get \n");
+
+        rc = EIP207_Global_HWRevision_Get(&Global_IOArea, &Capabilities);
+        if (rc != EIP207_GLOBAL_NO_ERROR)
+        {
+            LOG_CRIT("GlobalControl207_Init: "
+                     "EIP207_Global_HWRevision_Get() failed\n");
+            goto exit; // error
+        }
+
+#ifndef GLOBALCONTROL_BUILD
+#ifdef ADAPTER_CS_RC_SUPPORT
+        Adapter_RC_EIP207_Configure(
+                (ADAPTER_CS_TRC_ENABLED != 0),
+                (ADAPTER_CS_ARC4RC_ENABLED != 0) &&
+                                 Capabilities.EIP207_Options.fARC4Present,
+                Capabilities.EIP207_Options.fCombinedTRC_ARC4);
+#endif // ADAPTER_CS_RC_SUPPORT
+#endif // GLOBALCONTROL_BUILD
+    }
+
+    if (fLoadFirmware)
+    {
+        if (GlobalControl207Lib_Firmware_Load(true) != 0)
+            goto exit;
+    }
+
+    {
+        EIP207_Firmware_Config_t FWConfig;
+        ZEROINIT(FWConfig);
+#if defined(ADAPTER_CS_GLOBAL_IOTOKEN_METADATA_ENABLE) || \
+    defined(ADAPTER_CS_GLOBAL_CFH_ENABLE)
+        FWConfig.fTokenExtensionsEnable = true;
+#else
+        FWConfig.fTokenExtensionsEnable = false;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_INCREMENT_PKTID
+        FWConfig.fIncrementPktID = true;
+#else
+        FWConfig.fIncrementPktID = false;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_ECN_CONTROL
+        FWConfig.ECNControl = ADAPTER_CS_GLOBAL_ECN_CONTROL;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_DEFER_CCS
+        FWConfig.fDTLSDeferCCS = true;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_DEFER_ALERT
+        FWConfig.fDTLSDeferAlert = true;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_DEFER_HANDSHAKE
+        FWConfig.fDTLSDeferHandshake = true;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_DEFER_APPDATA
+        FWConfig.fDTLSDeferAppData = true;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_DEFER_CAPWAP
+        FWConfig.fDTLSDeferCAPWAP = true;
+#endif
+#ifdef ADAPTER_CS_GLOBAL_DTLS_HDR_ALIGN
+        FWConfig.DTLSRecordHeaderAlign = ADAPTER_CS_GLOBAL_DTLS_HDR_ALIGN;
+#endif
+        FWConfig.TransformRedirEnable = ADAPTER_CS_GLOBAL_TRANSFORM_REDIRECT_ENABLE;
+#ifdef ADAPTER_CS_GLOBAL_REDIR_RING
+        FWConfig.fRedirRingEnable = true;
+        FWConfig.RedirRing = ADAPTER_CS_GLOBAL_REDIR_RING;
+#endif
+        // Configure the EIP-207 Firmware meta-data or CFH presence
+        // in the ICE scratch-path RAM
+        for (i = 0; i < NofCEs; i++)
+        {
+            EIP207_Global_Firmware_Configure(Device, i, &FWConfig);
+            if (FWConfig.fIncrementPktID)
+            {   /* Give each engine its own range of PktID values */
+                FWConfig.PktID += 4096;
+            }
+        }
+    }
+    Global_IsInitialized = true;
+    GC207_Rc = EIP207_GLOBAL_CONTROL_NO_ERROR; // success
+
+exit:
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID);
+
+    return GC207_Rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_UnInit
+ */
+GlobalControl207_Error_t
+GlobalControl207_UnInit(void)
+{
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    if (!Global_IsInitialized)
+    {
+        LOG_CRIT("GlobalControl207_UnInit: called while not initialized\n");
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_USE_ORDER;
+    }
+
+    (void)RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID, false);
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID);
+
+    Global_IsInitialized = false;
+
+    return EIP207_GLOBAL_CONTROL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_Status_Get
+ */
+GlobalControl207_Error_t
+GlobalControl207_Status_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_Status_t * const Status_p)
+{
+    EIP207_Global_Error_t rc;
+    bool fFatalError;
+
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP207_Global_Status_Get \n");
+
+    rc = EIP207_Global_Status_Get(&Global_IOArea,
+                                  CE_Number,
+                                  Status_p,
+                                  &fFatalError);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP207_GLOBAL_NO_ERROR)
+    {
+        if (fFatalError)
+            LOG_CRIT("GlobalControl207_Status_Get: Fatal Error detected, "
+                     "reset required!\n");
+
+        return EIP207_GLOBAL_CONTROL_NO_ERROR;
+    }
+    else if (rc == EIP207_GLOBAL_ARGUMENT_ERROR)
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_GlobalStats_Get
+ */
+GlobalControl207_Error_t
+GlobalControl207_GlobalStats_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_GlobalStats_t * const GlobalStats_p)
+{
+    EIP207_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP207_Global_GlobalStats_Get \n");
+
+    rc = EIP207_Global_GlobalStats_Get(&Global_IOArea,
+                                       CE_Number,
+                                       GlobalStats_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP207_GLOBAL_NO_ERROR)
+        return EIP207_GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP207_GLOBAL_ARGUMENT_ERROR)
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl207_ClockCount_Get
+ */
+GlobalControl207_Error_t
+GlobalControl207_ClockCount_Get(
+        const unsigned int CE_Number,
+        GlobalControl207_Clock_t * const Clock_p)
+{
+    EIP207_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t %s \n", __func__);
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP207_Global_ClockCount_Get \n");
+
+    rc = EIP207_Global_ClockCount_Get(&Global_IOArea,
+                                      CE_Number,
+                                      Clock_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP207_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP207_GLOBAL_NO_ERROR)
+        return EIP207_GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP207_GLOBAL_ARGUMENT_ERROR)
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return EIP207_GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*--------------------- -------------------------------------------------------
+ * GlobalControl207_Firmware_Configure
+ */
+GlobalControl207_Error_t
+GlobalControl207_Firmware_Configure(
+        GlobalControl_Firmware_Config_t * const FWConfig_p)
+{
+    unsigned i;
+    Device_Handle_t Device;
+    unsigned int NofCEs;
+    Device = Device_Find(ADAPTER_CS_GLOBAL_DEVICE_NAME);
+    GlobalControl97_Interfaces_Get(&NofCEs, NULL, NULL, NULL);
+    if (FWConfig_p == NULL)
+        return EIP207_GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    FWConfig_p->PktID = 0;
+    // Configure the EIP-207 Firmware meta-data or CFH presence
+    // in the ICE scratch-path RAM
+    for (i = 0; i < NofCEs; i++)
+    {
+        EIP207_Global_Firmware_Configure(Device, i, FWConfig_p);
+        if (FWConfig_p->fIncrementPktID)
+        {   /* Give each engine its own range of PktID values */
+            FWConfig_p->PktID += 4096;
+        }
+    }
+
+    return EIP207_GLOBAL_CONTROL_NO_ERROR;
+
+}
+
+
+/* end of file adapter_global_eip207.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c
new file mode 100644
index 0000000..f31fa52
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip74.c
@@ -0,0 +1,630 @@
+/* api_global_eip74.c
+ *
+ * Deterministic Random Bit Generator (EIP-74) Global Control Initialization
+ * Adapter. The EIP-74 is used to generate pseudo-random IVs for outbound
+ * operations in CBC mode.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "api_global_eip74.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Configuration.
+#include "c_adapter_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint8_t
+
+// memcpy
+#include "clib.h"
+
+// EIP-73 Driver Library.
+#include "eip74.h"
+
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+
+// Logging API
+#include "log.h"                // Log_*, LOG_*
+
+// Adapter interrupts API
+#include "adapter_interrupts.h" // Adapter_Interrupt_*
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/* Put all adapter local variables in one structure */
+static struct {
+    EIP74_IOArea_t IOArea;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    GlobalControl74_NotifyFunction_t Notify_CBFunc;
+#endif
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    GlobalControl74_Configuration_t CachedConfig;
+    bool fInitialized;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    bool fInterruptEnabled;
+#endif
+#endif
+} EIP74State;
+
+
+static const  GlobalControl74_Capabilities_t Global_CapabilitiesString =
+{
+  "EIP-74 v_._p_"// szTextDescription
+};
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Init
+ */
+static GlobalControl74_Error_t
+GlobalControl74Lib_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p);
+
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Resune
+ */
+static int
+GlobalControl74Lib_Resune(
+        void *p)
+{
+    uint8_t Entropy[48];
+    IDENTIFIER_NOT_USED(p);
+    if (EIP74State.fInitialized)
+    {
+        /* Note we should add fresh random data here */
+        ZEROINIT(Entropy);
+        if (GlobalControl74Lib_Init(&EIP74State.CachedConfig, Entropy) !=
+            GLOBAL_CONTROL_EIP74_NO_ERROR)
+        {
+            return -1;
+        }
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+        if (EIP74State.fInitialized && EIP74State.fInterruptEnabled)
+        {
+            Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+            Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+        }
+#endif
+    }
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Suspend
+ */
+static int
+GlobalControl74Lib_Suspend(
+        void *p)
+{
+    IDENTIFIER_NOT_USED(p);
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    if (EIP74State.fInitialized && EIP74State.fInterruptEnabled)
+    {
+        Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+        Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+    }
+#endif
+    return 0;
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_CopyKeyMat
+ *
+ * Copy a key represented as a byte array into a word array..
+ *
+ * Destination_p (input)
+ *   Destination (word-aligned) of the word array
+ *
+ * Source_p (input)
+ *   Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ *   Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+static void
+GlobalControl74Lib_CopyKeyMat(
+        uint32_t * const Destination_p,
+        const uint8_t * const Source_p,
+        const unsigned int KeyByteCount)
+{
+    uint32_t *dst = Destination_p;
+    const uint8_t *src = Source_p;
+    unsigned int i,j;
+    uint32_t w;
+    if (Destination_p == NULL)
+        return;
+    for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
+    {
+        w=0;
+        for(j=0; j<sizeof(uint32_t); j++)
+            w=(w<<8)|(*src++);
+        *dst++ = w;
+    }
+}
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * GlobalControl74_InterruptHandlerNotify
+ */
+static void
+GlobalControl74_InterruptHandlerNotify(
+        const int nIRQ,
+        const unsigned int flags)
+{
+    GlobalControl74_NotifyFunction_t CB_Func = EIP74State.Notify_CBFunc;
+
+    IDENTIFIER_NOT_USED(nIRQ);
+    IDENTIFIER_NOT_USED(flags);
+
+    LOG_INFO("GlobalControl74_InterruptHandlerNotify\n");
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInterruptEnabled = true;
+#endif
+
+    EIP74State.Notify_CBFunc = NULL;
+    if (CB_Func != NULL)
+    {
+        LOG_INFO("\t Invoking callback\n");
+        CB_Func();
+    }
+}
+#endif
+/*----------------------------------------------------------------------------
+ * GlobalControl74Lib_Init
+ *
+ * This function performs the initialization of the EIP-74 Deterministic
+ * Random Bit Generator.
+ *
+ * Note: the Device was already found and the IOArea is already initialized.
+ *
+ * Configuration_p (input)
+ *     Configuration parameters of the DRBG.
+ *
+ * Entropy_p (input)
+ *     Pointer to a string of exactly 48 bytes that serves as the entropy.
+ *     to initialize the DRBG.
+ *
+ * Return value
+ *     GLOBAL_CONTROL_EIP74_NO_ERROR : initialization performed successfully
+ *     GLOBAL_CONTROL_EIP74_ERROR_INTERNAL : initialization failed
+ */
+static GlobalControl74_Error_t
+GlobalControl74Lib_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    EIP74_Configuration_t Conf;
+    unsigned LoopCounter = ADAPTER_EIP74_RESET_MAX_RETRIES;
+    uint32_t Entropy[12];
+
+    Rc = EIP74_Reset(&EIP74State.IOArea);
+    do
+    {
+        if (Rc == EIP74_BUSY_RETRY_LATER)
+        {
+            LoopCounter--;
+            if (LoopCounter == 0)
+            {
+                LOG_CRIT("%s EIP74 reset timed out\n",__func__);
+                return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+            }
+            Rc = EIP74_Reset_IsDone(&EIP74State.IOArea);
+        }
+        else if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74 reset error\n",__func__);
+            return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+        }
+    } while (Rc != EIP74_NO_ERROR);
+
+    if (Configuration_p->GenerateBlockSize == 0)
+    {
+        Conf.GenerateBlockSize =  ADAPTER_EIP74_GEN_BLK_SIZE;
+    }
+    else
+    {
+        Conf.GenerateBlockSize = Configuration_p->GenerateBlockSize;
+    }
+
+    if (Configuration_p->ReseedThr == 0)
+    {
+        Conf.ReseedThr =  ADAPTER_EIP74_RESEED_THR;
+    }
+    else
+    {
+        Conf.ReseedThr = Configuration_p->ReseedThr;
+    }
+
+    if (Configuration_p->ReseedThrEarly == 0)
+    {
+        Conf.ReseedThrEarly =  ADAPTER_EIP74_RESEED_THR_EARLY;
+    }
+    else
+    {
+        Conf.ReseedThrEarly = Configuration_p->ReseedThrEarly;
+    }
+
+    Rc = EIP74_Configure(&EIP74State.IOArea, &Conf);
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be configured\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    GlobalControl74Lib_CopyKeyMat(Entropy, Entropy_p, 48);
+
+    Rc = EIP74_Instantiate(&EIP74State.IOArea, Entropy, Configuration_p->fStuckOut);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be instantiated\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Capabilities_Get
+ */
+void
+GlobalControl74_Capabilities_Get(
+        GlobalControl74_Capabilities_t * const Capabilities_p)
+{
+    Device_Handle_t Device;
+    uint8_t Versions[3];
+    LOG_INFO("\n\t\t\t GlobalControl74_Capabilities_Get\n");
+
+    memcpy(Capabilities_p, &Global_CapabilitiesString,
+           sizeof(Global_CapabilitiesString));
+
+    Device = Device_Find(ADAPTER_EIP74_DEVICE_NAME);
+    if (Device == NULL)
+    {
+        LOG_CRIT("%s EIP74 Device not found\n",__func__);
+        return;
+    }
+
+    {
+        EIP74_Capabilities_t Capabilities;
+        EIP74_Error_t Rc;
+
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                RPM_FLAG_SYNC) != RPM_SUCCESS)
+            return;
+
+        Rc = EIP74_HWRevision_Get(Device, &Capabilities);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                       RPM_FLAG_ASYNC);
+
+        if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74_Capaboilities_Get() failed\n",__func__);
+            return;
+        }
+
+        Log_FormattedMessage(
+            "EIP74 options: Nof Clients=%u Nof AESCores=%u\n"
+            "\t\tAESSpeed=%u FIFODepth=%u\n",
+            Capabilities.HW_Options.ClientCount,
+            Capabilities.HW_Options.AESCoreCount,
+            Capabilities.HW_Options.AESSpeed,
+            Capabilities.HW_Options.FIFODepth);
+
+
+        Versions[0] = Capabilities.HW_Revision.MajHWRevision;
+        Versions[1] = Capabilities.HW_Revision.MinHWRevision;
+        Versions[2] = Capabilities.HW_Revision.HWPatchLevel;
+    }
+
+    {
+        char * p = Capabilities_p->szTextDescription;
+        int VerIndex = 0;
+        int i = 0;
+
+        while(p[i])
+        {
+            if (p[i] == '_' && VerIndex < 3)
+            {
+                if (Versions[VerIndex] > 9)
+                    p[i] = '?';
+                else
+                    p[i] = '0' + Versions[VerIndex];
+
+                VerIndex++;
+            }
+
+            i++;
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Init
+ */
+GlobalControl74_Error_t
+GlobalControl74_Init(
+        const GlobalControl74_Configuration_t * const Configuration_p,
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    Device_Handle_t Device;
+
+    LOG_INFO("\n\t\t\t GlobalControl74_Init\n");
+
+    Device = Device_Find(ADAPTER_EIP74_DEVICE_NAME);
+    if (Device == NULL)
+    {
+        LOG_CRIT("%s EIP74 Device not found\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED;
+    }
+
+
+    Rc = EIP74_Init(&EIP74State.IOArea, Device);
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be initialized\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_NOT_IMPLEMENTED;
+    }
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                    GlobalControl74Lib_Suspend,
+                                    GlobalControl74Lib_Resume) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    if (GlobalControl74Lib_Init(Configuration_p,Entropy_p) !=
+        GLOBAL_CONTROL_EIP74_NO_ERROR)
+    {
+        (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInitialized = true;
+    EIP74State.CachedConfig = *Configuration_p;
+#endif
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_ERR_IRQ,
+                                 GlobalControl74_InterruptHandlerNotify);
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_RES_IRQ,
+                                 GlobalControl74_InterruptHandlerNotify);
+#endif
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_UnInit
+ */
+GlobalControl74_Error_t
+GlobalControl74_UnInit(void)
+{
+    EIP74_Error_t Rc;
+    unsigned LoopCounter = ADAPTER_EIP74_RESET_MAX_RETRIES;
+
+    LOG_INFO("\n\t\t\t GlobalControl74_UnInit\n");
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_ERR_IRQ, NULL);
+    Adapter_Interrupt_SetHandler(ADAPTER_EIP74_RES_IRQ, NULL);
+    Adapter_Interrupt_Disable(ADAPTER_EIP74_ERR_IRQ, 0);
+    Adapter_Interrupt_Disable(ADAPTER_EIP74_RES_IRQ, 0);
+#endif
+    (void)RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID, false);
+
+    Rc = EIP74_Reset(&EIP74State.IOArea);
+    do
+    {
+        if (Rc == EIP74_BUSY_RETRY_LATER)
+        {
+            LoopCounter--;
+            if (LoopCounter == 0)
+            {
+                LOG_CRIT("%s EIP74 reset timed out\n",__func__);
+                (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+                return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+            }
+            Rc = EIP74_Reset_IsDone(&EIP74State.IOArea);
+        }
+        else if (Rc != EIP74_NO_ERROR)
+        {
+            LOG_CRIT("%s EIP74 reset error\n",__func__);
+            (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+            return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+        }
+    } while (Rc != EIP74_NO_ERROR);
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID);
+
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+    EIP74State.fInitialized = false;
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+    EIP74State.fInterruptEnabled = false;
+#endif
+#endif
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Reseed
+ */
+GlobalControl74_Error_t
+GlobalControl74_Reseed(
+        const uint8_t * const Entropy_p)
+{
+    EIP74_Error_t Rc;
+    uint32_t Entropy[12];
+    LOG_INFO("\n\t\t\t GlobalControl74_Reseed\n");
+
+
+    GlobalControl74Lib_CopyKeyMat(Entropy, Entropy_p, 48);
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Reseed(&EIP74State.IOArea, Entropy);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be reseeded\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Status_Get
+ */
+GlobalControl74_Error_t
+GlobalControl74_Status_Get(
+        GlobalControl74_Status_t * const Status_p)
+{
+    EIP74_Error_t Rc;
+    EIP74_Status_t Status;
+    LOG_INFO("\n\t\t\t GlobalControl74_Status_Get\n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Status_Get(&EIP74State.IOArea, &Status);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 status could not be read\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    Status_p->GenerateBlockCount = Status.GenerateBlockCount;
+    Status_p->fStuckOut = Status.fStuckOut;
+    Status_p->fNotInitialized = Status.fNotInitialized;
+    Status_p->fReseedError = Status.fReseedError;
+    Status_p->fReseedWarning = Status.fReseedWarning;
+    Status_p->fInstantiated = Status.fInstantiated;
+    Status_p->AvailableCount = Status.AvailableCount;
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Clear
+ */
+GlobalControl74_Error_t
+GlobalControl74_Clear(void)
+{
+    EIP74_Error_t Rc;
+    LOG_INFO("\n\t\t\t GlobalControl74_Clear\n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+
+    Rc = EIP74_Clear(&EIP74State.IOArea);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP74_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (Rc != EIP74_NO_ERROR)
+    {
+        LOG_CRIT("%s EIP74 could not be cleared\n",__func__);
+        return GLOBAL_CONTROL_EIP74_ERROR_INTERNAL;
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+
+
+#ifdef ADAPTER_EIP74_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * GlobalControl74_Notify_Request
+ */
+GlobalControl74_Error_t
+GlobalControl74_Notify_Request(
+        GlobalControl74_NotifyFunction_t CBFunc_p)
+{
+    LOG_INFO("\n\t\t\t GlobalControl74_Notify_Request\n");
+    IDENTIFIER_NOT_USED(CBFunc_p);
+
+    EIP74State.Notify_CBFunc = CBFunc_p;
+    if (CBFunc_p != NULL)
+    {
+        Adapter_Interrupt_Enable(ADAPTER_EIP74_ERR_IRQ, 0);
+        Adapter_Interrupt_Enable(ADAPTER_EIP74_RES_IRQ, 0);
+#ifdef ADAPTER_PEC_RPM_EIP74_DEVICE0_ID
+        EIP74State.fInterruptEnabled = true;
+#endif
+    }
+
+    return GLOBAL_CONTROL_EIP74_NO_ERROR;
+}
+#endif
+
+
+/* end of file adapter_global_eip74.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip97.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip97.c
new file mode 100644
index 0000000..cb6ae1d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_eip97.c
@@ -0,0 +1,884 @@
+/* adapter_global_eip97.c
+ *
+ * Security-IP-97 Global Control Adapter
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "api_global_eip97.h"
+#include "adapter_global_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_global.h"
+
+#ifndef GLOBALCONTROL_BUILD
+#include "adapter_ring_eip202.h" // Ring EIP-202 interface to pass
+                                 // config params from Global Control
+#endif
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool, IDENTIFIER_NOT_USED
+
+// Driver Framework C Library API
+#include "clib.h"               // memcpy, ZEROINIT
+
+// EIP-97 Driver Library Global Control API
+#include "eip97_global_event.h" // Event Management
+#include "eip97_global_init.h"  // Init/Uninit
+#include "eip97_global_prng.h"  // PRNG Control
+
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+
+// Logging API
+#include "log.h"                // Log_*, LOG_*
+
+#ifdef GLOBALCONTROL_BUILD
+#include "shdevxs_init.h"       // SHDevXS_Global_init()
+#endif
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    bool fCached;
+
+    GlobalControl97_Ring_PE_Map_t RingPEMap;
+
+} GlobalControl97_Ring_PE_Map_Cache_t;
+
+typedef struct
+{
+    bool fCached;
+
+    GlobalControl97_PRNG_Reseed_t   ReseedData;
+
+} GlobalControl97_PRNG_Cache_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static EIP97_Global_IOArea_t Global_IOArea;
+static bool Global_IsInitialized;
+static bool Global_PRNG_Present;
+
+static const  GlobalControl97_Capabilities_t Global_CapabilitiesString =
+{
+  "EIP-97 v_._p_  with EIP-202 v_._p_ and EIP-96 v_._p_, "
+  "#PE=__ #rings=__ central-prng=_"// szTextDescription
+};
+
+static unsigned int GlobalControl97_NofPEs;
+static unsigned int GlobalControl97_NofRings;
+static unsigned int GlobalControl97_NofLAInterfaces;
+static unsigned int GlobalControl97_NofInlineInterfaces;
+
+// Cached values for RPM resume callback
+static GlobalControl97_Ring_PE_Map_Cache_t GlobalControl97_RingPEMap [ADAPTER_GLOBAL_EIP97_NOF_PES];
+static GlobalControl97_PRNG_Cache_t GlobalControl97_Prng [ADAPTER_GLOBAL_EIP97_NOF_PES];
+
+
+/*----------------------------------------------------------------------------
+ * YesNo
+ */
+static const char *
+YesNo(
+        const bool b)
+{
+    if (b)
+        return "Yes";
+    else
+        return "No";
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97Lib_Resume
+ *
+ */
+static int
+GlobalControl97Lib_Resume(void * p)
+{
+    unsigned int i;
+    EIP97_Global_Error_t rc;
+    EIP97_Global_Capabilities_t Capabilities;
+
+    IDENTIFIER_NOT_USED(p);
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_Init \n");
+
+    rc = EIP97_Global_Init(&Global_IOArea,
+                           Device_Find(ADAPTER_GLOBAL_DEVICE_NAME));
+    if (rc != EIP97_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP97_Global_Init() returned error %d\n", __func__, rc);
+        return -1; // error
+    }
+
+    rc = EIP97_Global_HWRevision_Get(&Global_IOArea, &Capabilities);
+    if (rc != EIP97_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP97_Global_HWRevision_Get() returned error %d\n", __func__, rc);
+        return -1; // error
+    }
+    GlobalControl97_NofPEs = MIN(Capabilities.EIP202_Options.NofPes, ADAPTER_GLOBAL_EIP97_NOF_PES);
+    for (i = 0; i < GlobalControl97_NofPEs; i++)
+    {
+        if (GlobalControl97_RingPEMap[i].fCached)
+        {
+            LOG_INFO("\n\t\t\t\t EIP97_Global_Configure \n");
+
+            rc = EIP97_Global_Configure(&Global_IOArea,
+                                        i,
+                                        &GlobalControl97_RingPEMap[i].RingPEMap);
+            if (rc != EIP97_GLOBAL_NO_ERROR)
+            {
+                LOG_CRIT("%s: EIP97_Global_Configure() error %d for PE %d\n",
+                         __func__,
+                         rc,
+                         i);
+                return -2; // error
+            }
+        }
+
+        if (GlobalControl97_Prng[i].fCached && Global_PRNG_Present)
+        {
+            LOG_INFO("\n\t\t\t\t EIP97_Global_PRNG_Reseed \n");
+
+            rc = EIP97_Global_PRNG_Reseed(&Global_IOArea,
+                                          i,
+                                          &GlobalControl97_Prng[i].ReseedData);
+            if (rc != EIP97_GLOBAL_NO_ERROR)
+            {
+                LOG_CRIT("%s: EIP97_Global_PRNG_Reseed() error %d for PE %d\n",
+                         __func__,
+                         rc,
+                         i);
+                return -3; // error
+            }
+        }
+    } // for
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Capabilities_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_Capabilities_Get(
+        GlobalControl97_Capabilities_t * const Capabilities_p)
+{
+    uint8_t Versions[14];
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Capabilities_Get \n");
+
+    memcpy(Capabilities_p, &Global_CapabilitiesString,
+           sizeof(Global_CapabilitiesString));
+
+    {
+        EIP97_Global_Error_t rc;
+        EIP97_Global_Capabilities_t Capabilities;
+
+        ZEROINIT(Capabilities);
+
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                RPM_FLAG_SYNC) != RPM_SUCCESS)
+            return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+        LOG_INFO("\n\t\t\t\t EIP97_Global_HWRevision_Get \n");
+
+        rc = EIP97_Global_HWRevision_Get(&Global_IOArea, &Capabilities);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                       RPM_FLAG_ASYNC);
+
+        if (rc != EIP97_GLOBAL_NO_ERROR)
+        {
+            LOG_CRIT("GlobalControl97_Capabilities_Get: returned error");
+            return GLOBAL_CONTROL_ERROR_INTERNAL;
+        }
+
+        // Show those capabilities not propagated to higher layer.
+        LOG_CRIT("GlobalControl97_Capabilities_Get\n");
+        LOG_CRIT("EIP202: PEs=%d rings=%d 64-bit=%s, fill level extension=%s\n"
+                 "CF size=%d RF size=%d DMA len = %d "
+                 "Align=%d HDW=%d HostIfc=%d\n",
+                 Capabilities.EIP202_Options.NofPes,
+                 Capabilities.EIP202_Options.NofRings,
+                 YesNo(Capabilities.EIP202_Options.fAddr64),
+                 YesNo(Capabilities.EIP202_Options.fExpPlf),
+                 Capabilities.EIP202_Options.CF_Size,
+                 Capabilities.EIP202_Options.RF_Size,
+                 Capabilities.EIP202_Options.DMA_Len,
+                 Capabilities.EIP202_Options.TgtAlign,
+                 Capabilities.EIP202_Options.HDW,
+                 Capabilities.EIP202_Options.HostIfc);
+        LOG_CRIT("EIP96 options:\n"
+                 "AES: %s with CFB/OFB: %s Fast: %s\n"
+                 "DES: %s with CFB/OFB: %s Fast: %s\n"
+                 "ARCFOUR level: %d\n"
+                 "AES-XTS: %s Wireless crypto: %s\n"
+                 "MD5: %s SHA1: %s Fast: %s SHA256: %s SHA512: %s\n"
+                 "(X)CBC-MAC: %s Fast: %s All key sizes: %s GHASH %s\n",
+                 YesNo(Capabilities.EIP96_Options.fAES),
+                 YesNo(Capabilities.EIP96_Options.fAESfb),
+                 YesNo(Capabilities.EIP96_Options.fAESspeed),
+                 YesNo(Capabilities.EIP96_Options.fDES),
+                 YesNo(Capabilities.EIP96_Options.fDESfb),
+                 YesNo(Capabilities.EIP96_Options.fDESspeed),
+                 Capabilities.EIP96_Options.ARC4,
+                 YesNo(Capabilities.EIP96_Options.fAES_XTS),
+                 YesNo(Capabilities.EIP96_Options.fWireless),
+                 YesNo(Capabilities.EIP96_Options.fMD5),
+                 YesNo(Capabilities.EIP96_Options.fSHA1),
+                 YesNo(Capabilities.EIP96_Options.fSHA1speed),
+                 YesNo(Capabilities.EIP96_Options.fSHA224_256),
+                 YesNo(Capabilities.EIP96_Options.fSHA384_512),
+                 YesNo(Capabilities.EIP96_Options.fXCBC_MAC),
+                 YesNo(Capabilities.EIP96_Options.fCBC_MACspeed),
+                 YesNo(Capabilities.EIP96_Options.fCBC_MACkeylens),
+                 YesNo(Capabilities.EIP96_Options.fGHASH));
+        LOG_CRIT("EIP97 options: PEs=%d, In Dbuf size=%d In Tbuf size=%d,"
+                 " Out Dbuf size=%d, Out Tbuf size=%d, Central PRNG: %s\n"
+                 "Token Generator: %s, Transform Record Cache: %s\n",
+                 Capabilities.EIP97_Options.NofPes,
+                 Capabilities.EIP97_Options.in_dbuf_size,
+                 Capabilities.EIP97_Options.in_tbuf_size,
+                 Capabilities.EIP97_Options.out_dbuf_size,
+                 Capabilities.EIP97_Options.out_tbuf_size,
+                 YesNo(Capabilities.EIP97_Options.central_prng),
+                 YesNo(Capabilities.EIP97_Options.tg),
+                 YesNo(Capabilities.EIP97_Options.trc));
+        LOG_CRIT("EIP206 options: PE type=%d InClassifier=%d OutClassifier=%d "
+                 "MAC chans=%d \n"
+                 "InDBuf=%dkB InTBuf=%dkB OutDBuf=%dkB OutTBuf=%dkB\n",
+                 Capabilities.EIP206_Options.PE_Type,
+                 Capabilities.EIP206_Options.InClassifier,
+                 Capabilities.EIP206_Options.OutClassifier,
+                 Capabilities.EIP206_Options.NofMAC_Channels,
+                 Capabilities.EIP206_Options.InDbufSizeKB,
+                 Capabilities.EIP206_Options.InTbufSizeKB,
+                 Capabilities.EIP206_Options.OutDbufSizeKB,
+                 Capabilities.EIP206_Options.OutTbufSizeKB);
+
+        Versions[0] = Capabilities.EIP97_Version.MajHWRevision;
+        Versions[1] = Capabilities.EIP97_Version.MinHWRevision;
+        Versions[2] = Capabilities.EIP97_Version.HWPatchLevel;
+
+        Versions[3] = Capabilities.EIP202_Version.MajHWRevision;
+        Versions[4] = Capabilities.EIP202_Version.MinHWRevision;
+        Versions[5] = Capabilities.EIP202_Version.HWPatchLevel;
+
+        Versions[6] = Capabilities.EIP96_Version.MajHWRevision;
+        Versions[7] = Capabilities.EIP96_Version.MinHWRevision;
+        Versions[8] = Capabilities.EIP96_Version.HWPatchLevel;
+
+        Versions[9]  = Capabilities.EIP202_Options.NofPes / 10;
+        Versions[10] = Capabilities.EIP202_Options.NofPes % 10;
+        Versions[11] = Capabilities.EIP202_Options.NofRings / 10;
+        Versions[12] = Capabilities.EIP202_Options.NofRings % 10;
+        Versions[13] = (uint8_t)Capabilities.EIP97_Options.central_prng;
+    }
+
+    {
+        char * p = Capabilities_p->szTextDescription;
+        int VerIndex = 0;
+        int i = 0;
+
+        while(p[i])
+        {
+            if (p[i] == '_')
+            {
+                if (Versions[VerIndex] > 9)
+                    p[i] = '?';
+                else
+                    p[i] = '0' + Versions[VerIndex];
+
+                VerIndex++;
+            }
+
+            i++;
+        }
+    }
+
+    return GLOBAL_CONTROL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Init
+ */
+GlobalControl97_Error_t
+GlobalControl97_Init(
+        const bool fHWResetDone)
+{
+    EIP97_Global_Error_t rc;
+    GlobalControl97_Error_t GC97_Rc = GLOBAL_CONTROL_ERROR_INTERNAL;
+    Device_Handle_t dev;
+    EIP97_Global_Capabilities_t Capabilities;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Init \n");
+
+    if (Global_IsInitialized)
+    {
+        LOG_CRIT("GlobalControl97_Init: called while already initialized\n");
+        return GLOBAL_CONTROL_ERROR_BAD_USE_ORDER;
+    }
+
+    dev = Device_Find(ADAPTER_GLOBAL_DEVICE_NAME);
+    if (dev == NULL)
+    {
+        LOG_CRIT("GlobalControl97_Init: Could not find device\n");
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+    }
+
+    ZEROINIT(GlobalControl97_RingPEMap);
+    ZEROINIT(GlobalControl97_Prng);
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                    NULL, // Suspend callback not used
+                                    GlobalControl97Lib_Resume) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    if (!fHWResetDone)
+    {
+        LOG_INFO("\n\t\t\t\t EIP97_Global_Reset \n");
+
+        // Need to do a software reset first.
+        rc = EIP97_Global_Reset(&Global_IOArea, dev);
+        if (rc == EIP97_GLOBAL_BUSY_RETRY_LATER)
+        {
+            unsigned int tries = 0;
+            do {
+                LOG_INFO("\n\t\t\t\t EIP97_Global_Reset_IsDone \n");
+
+                rc = EIP97_Global_Reset_IsDone(&Global_IOArea);
+                if (rc != EIP97_GLOBAL_NO_ERROR &&
+                    rc != EIP97_GLOBAL_BUSY_RETRY_LATER)
+                {
+                    LOG_CRIT("GlobalControl97_Init:"
+                             " Error from EIP97_Global_Reset_IsDone\n");
+                    goto exit; // error
+                }
+                tries ++;
+                if (tries > ADAPTER_GLOBAL_RESET_MAX_RETRIES)
+                {
+                    LOG_CRIT("GlobalControl97_Init: Reset timeout\n");
+                    goto exit; // error
+                }
+            } while (rc == EIP97_GLOBAL_BUSY_RETRY_LATER);
+        }
+        else if (rc != EIP97_GLOBAL_NO_ERROR)
+        {
+            LOG_CRIT("GlobalControl97_Init: Error from EIP97_Global_Reset\n");
+            goto exit; // error
+        }
+    }
+
+    ZEROINIT(Capabilities);
+
+    rc = EIP97_Global_HWRevision_Get(&Global_IOArea, &Capabilities);
+    if (rc != EIP97_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("GlobalControl97_Init: returned error");
+        goto exit; // error
+    }
+    Global_PRNG_Present = !Capabilities.EIP97_Options.central_prng;
+
+    if (GlobalControl97Lib_Resume(NULL) != 0)
+        goto exit; // error
+    else
+    {
+        Global_IsInitialized = true;
+
+        GlobalControl97_NofRings = Capabilities.EIP202_Options.NofRings;
+        GlobalControl97_NofLAInterfaces = Capabilities.EIP202_Options2.NofLA_Ifs;
+        GlobalControl97_NofInlineInterfaces = Capabilities.EIP202_Options2.NofIN_Ifs;
+
+#ifdef GLOBALCONTROL_BUILD
+        if (SHDevXS_Global_Init() != 0)
+        {
+            LOG_CRIT(
+                "GlobalControl97_Init: SHDevXS_Global_Init() returned error");
+            goto exit; // error
+        }
+#else
+        // Pass HW default configuration parameters obtained via
+        // the Global Control interface to the Ring Control
+        // for its automatic configuration
+        Adapter_Ring_EIP202_Configure(Capabilities.EIP202_Options.HDW,
+                                      Capabilities.EIP202_Options.CF_Size,
+                                      Capabilities.EIP202_Options.RF_Size);
+#endif
+
+        GC97_Rc = GLOBAL_CONTROL_NO_ERROR; // success
+    }
+
+exit:
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID);
+
+    return GC97_Rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_UnInit
+ */
+GlobalControl97_Error_t
+GlobalControl97_UnInit(void)
+{
+    EIP97_Global_Error_t rc;
+    GlobalControl97_Error_t GC97_Rc = GLOBAL_CONTROL_ERROR_INTERNAL;
+    Device_Handle_t dev;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_UnInit \n");
+
+    if (!Global_IsInitialized)
+    {
+        LOG_CRIT("GlobalControl97_UnInit: called while not initialized\n");
+        return GLOBAL_CONTROL_ERROR_BAD_USE_ORDER;
+    }
+
+    dev = Device_Find(ADAPTER_GLOBAL_DEVICE_NAME);
+    if (dev == NULL)
+    {
+        LOG_CRIT("GlobalControl97_UnInit: Could not find device\n");
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+    }
+
+    if (RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                      true) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_Reset \n");
+
+    rc = EIP97_Global_Reset(&Global_IOArea, dev);
+    if (rc == EIP97_GLOBAL_BUSY_RETRY_LATER)
+    {
+        unsigned int tries = 0;
+        do {
+            LOG_INFO("\n\t\t\t\t EIP97_Global_Reset_IsDone \n");
+
+            rc = EIP97_Global_Reset_IsDone(&Global_IOArea);
+            if (rc != EIP97_GLOBAL_NO_ERROR &&
+                rc != EIP97_GLOBAL_BUSY_RETRY_LATER)
+            {
+                LOG_CRIT("GlobalControl97_UnInit:"
+                         " Error from EIP97_Global_Reset_IsDone\n");
+                goto exit; // error
+            }
+                tries ++;
+                if (tries > ADAPTER_GLOBAL_RESET_MAX_RETRIES)
+                {
+                    LOG_CRIT("GlobalControl97_UnInit: Reset timeout\n");
+                    goto exit; // error
+                }
+        } while (rc == EIP97_GLOBAL_BUSY_RETRY_LATER);
+    }
+    else if (rc != EIP97_GLOBAL_NO_ERROR)
+    {
+        LOG_CRIT("GlobalControl97_Init: Error from EIP97_Global_Reset\n");
+        goto exit; // error
+    }
+
+#ifdef GLOBALCONTROL_BUILD
+    SHDevXS_Global_UnInit();
+#endif
+
+    Global_IsInitialized = false;
+
+    GC97_Rc = GLOBAL_CONTROL_NO_ERROR; // success
+
+exit:
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID);
+
+    return GC97_Rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Configure
+ */
+GlobalControl97_Error_t
+GlobalControl97_Configure(
+        const unsigned int PE_Number,
+        const GlobalControl97_Ring_PE_Map_t * const RingPEMap_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Configure \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_Configure \n");
+
+    rc = EIP97_Global_Configure(&Global_IOArea, PE_Number, RingPEMap_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+    {
+        // Fall back on EIP97_Global_Configure() for PE_Number bounds check
+        GlobalControl97_RingPEMap[PE_Number].fCached   = true;
+        GlobalControl97_RingPEMap[PE_Number].RingPEMap = *RingPEMap_p;
+        return GLOBAL_CONTROL_NO_ERROR;
+    }
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_PRNG_Reseed
+ */
+GlobalControl97_Error_t
+GlobalControl97_PRNG_Reseed(
+        const unsigned int PE_Number,
+        const GlobalControl97_PRNG_Reseed_t * const ReseedData_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_PRNG_Reseed \n");
+
+    if (!Global_PRNG_Present)
+    {
+        LOG_CRIT("%s: PRNG device not present\n",__func__);
+        return GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED;
+    }
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_PRNG_Reseed \n");
+
+    rc = EIP97_Global_PRNG_Reseed(&Global_IOArea, PE_Number, ReseedData_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+    {
+        GlobalControl97_Prng[PE_Number].fCached     = true;
+        GlobalControl97_Prng[PE_Number].ReseedData  = *ReseedData_p;
+        return GLOBAL_CONTROL_NO_ERROR;
+    }
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_DFE_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_DFE_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_DFE_Status_t * const DFE_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_DFE_Status_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_DFE_Status_Get \n");
+
+    rc = EIP97_Global_DFE_Status_Get(&Global_IOArea, PE_Number, DFE_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_DSE_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_DSE_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_DSE_Status_t * const DSE_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_DSE_Status_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_DSE_Status_Get \n");
+
+    rc = EIP97_Global_DSE_Status_Get(&Global_IOArea, PE_Number, DSE_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID, RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Token_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_Token_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Token_Status_t * const Token_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Token_Status_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_EIP96_Token_Status_Get \n");
+
+    rc = EIP97_Global_EIP96_Token_Status_Get(&Global_IOArea,
+                                             PE_Number,
+                                             Token_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Context_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_Context_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Context_Status_t * const Context_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Context_Status_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_EIP96_Context_Status_Get \n");
+
+    rc = EIP97_Global_EIP96_Context_Status_Get(&Global_IOArea,
+                                               PE_Number,
+                                               Context_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Interrupt_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_Interrupt_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Interrupt_Status_t * const Interrupt_Status_p)
+{
+    IDENTIFIER_NOT_USED(PE_Number);
+
+    LOG_INFO("\n\t\t\t GlobalControl97_Interrupt_Status_Get \n");
+
+    // Not implemented yet, must use EIP-96 AIC
+    ZEROINIT(*Interrupt_Status_p);
+
+    return GLOBAL_CONTROL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_OutXfer_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_OutXfer_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_Output_Transfer_Status_t * const OutXfer_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_OutXfer_Status_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_EIP96_OutXfer_Status_Get \n");
+
+    rc = EIP97_Global_EIP96_OutXfer_Status_Get(&Global_IOArea,
+                                               PE_Number,
+                                               OutXfer_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_PRNG_Status_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_PRNG_Status_Get(
+        const unsigned int PE_Number,
+        GlobalControl97_PRNG_Status_t * const PRNG_Status_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_PRNG_Status_Get \n");
+
+    if (!Global_PRNG_Present)
+    {
+        return GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED;
+    }
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_EIP96_PRNG_Status_Get \n");
+
+    rc = EIP97_Global_EIP96_PRNG_Status_Get(&Global_IOArea,
+                                            PE_Number,
+                                            PRNG_Status_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+
+#ifdef ADAPTER_GLOBAL_DBG_STATISTICS
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Debug_Statistics_Get
+ */
+GlobalControl97_Error_t
+GlobalControl97_Debug_Statistics_Get(
+        GlobalControl97_Debug_Statistics_t * const Debug_Statistics_p)
+{
+    EIP97_Global_Error_t rc;
+
+    LOG_INFO("\n\t\t\t GlobalControl97_DSE_Debug_Statistics_Get \n");
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID,
+                            RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t\t EIP97_Global_Deubg_Statistics_Get \n");
+
+    rc = EIP97_Global_Debug_Statistics_Get(&Global_IOArea, Debug_Statistics_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP97_DEVICE_ID, RPM_FLAG_ASYNC);
+
+    if (rc == EIP97_GLOBAL_NO_ERROR)
+        return GLOBAL_CONTROL_NO_ERROR;
+    else if (rc == EIP97_GLOBAL_ARGUMENT_ERROR)
+        return GLOBAL_CONTROL_ERROR_BAD_PARAMETER;
+    else
+        return GLOBAL_CONTROL_ERROR_INTERNAL;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * GlobalControl97_Interfaces_Get
+ */
+void
+GlobalControl97_Interfaces_Get(
+    unsigned int * const NofPEs_p,
+    unsigned int * const NofRings_p,
+    unsigned int * const NofLAInterfaces_p,
+    unsigned int * const NofInlineInterfaces_p)
+{
+    if (NofPEs_p)
+        *NofPEs_p = GlobalControl97_NofPEs;
+    if (NofRings_p)
+        *NofRings_p = GlobalControl97_NofRings;
+    if (NofLAInterfaces_p)
+        *NofLAInterfaces_p = GlobalControl97_NofLAInterfaces;
+    if (NofInlineInterfaces_p)
+        *NofInlineInterfaces_p = GlobalControl97_NofInlineInterfaces;
+}
+
+
+/* end of file adapter_global_eip97.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_init.c
new file mode 100644
index 0000000..35a6cac
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_global_init.c
@@ -0,0 +1,417 @@
+/* adapter_global_init.c
+ *
+ * Global Control initialization module.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "adapter_global_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_global.h"   // ADAPTER_GLOBAL_PRNG_SEED
+
+// Global Control API: Packet I/O
+#include "api_global_eip97.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // uint8_t, uint32_t, bool
+
+// Driver Framework C Library API
+#include "clib.h"               // memcpy
+
+// EIP-97 Driver Library Global Control API
+#include "eip97_global_event.h" // Event Management
+#include "eip97_global_init.h"  // Init/Uninit
+#include "eip97_global_prng.h"  // PRNG Control
+
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+#include "log.h"                // Log API
+
+#include "adapter_global_internal.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static const uint32_t Global_PRNG_Key[8] = ADAPTER_GLOBAL_PRNG_SEED;
+
+/*----------------------------------------------------------------------------
+ * BoolToString()
+ *
+ * Convert boolean value to string.
+ */
+static const char *
+BoolToString(
+        const bool b)
+{
+    if (b)
+        return "true";
+    else
+        return "false";
+}
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_StatusReport()
+ *
+ * Obtain all available global status information from the EIP-97 driver
+ * and report it.
+ */
+static void
+Adapter_Global_StatusReport(void)
+{
+    GlobalControl97_Error_t rc;
+    unsigned int i;
+    unsigned int NofPEs;
+    GlobalControl97_Interfaces_Get(&NofPEs,NULL,NULL,NULL);
+
+    LOG_INFO("\n\t\t Adapter_Global_StatusReport \n");
+
+    LOG_CRIT("Global Status of the EIP-97\n");
+
+    for (i=0; i < NofPEs; i++)
+    {
+        LOG_CRIT("Packet Engine %d Status\n", i);
+        {
+            GlobalControl97_DFE_Status_t DFE_Status;
+
+            rc = GlobalControl97_DFE_Status_Get(i, &DFE_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("DFE Status: CD FIFO Words: %d, CDR ID: %d, DMA size: %d\n"
+                     "AtDMA busy: %s, DataDMA busy: %s, DMA err: %s\n",
+                     DFE_Status.CDFifoWord32Count,
+                     DFE_Status.CDR_ID,
+                     DFE_Status.DMASize,
+                     BoolToString(DFE_Status.fAtDMABusy),
+                     BoolToString(DFE_Status.fDataDMABusy),
+                     BoolToString(DFE_Status.fDMAError));
+        }
+
+        {
+            GlobalControl97_DSE_Status_t DSE_Status;
+
+            rc = GlobalControl97_DSE_Status_Get(i, &DSE_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("DSE Status: RD FIFO Words: %d, RDR ID: %d, DMA size: %d\n"
+                     "Data flush  busy: %s, DataDMA busy: %s, DMA err: %s\n",
+                     DSE_Status.RDFifoWord32Count,
+                     DSE_Status.RDR_ID,
+                     DSE_Status.DMASize,
+                     BoolToString(DSE_Status.fDataFlushBusy),
+                     BoolToString(DSE_Status.fDataDMABusy),
+                     BoolToString(DSE_Status.fDMAError));
+        }
+
+        {
+            GlobalControl97_Token_Status_t Token_Status;
+            rc = GlobalControl97_Token_Status_Get(i, &Token_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("Token Status: Active: %d, loc available: %s\n"
+                     "res available: %s, read active: %s, ccache active: %s\n"
+                     "cntx fetch: %s, res cntx: %s\n"
+                     "processing held: %s, busy: %s\n",
+                     Token_Status.ActiveTokenCount,
+                     BoolToString(Token_Status.fTokenLocationAvailable),
+                     BoolToString(Token_Status.fResultTokenAvailable),
+                     BoolToString(Token_Status.fTokenReadActive),
+                     BoolToString(Token_Status.fContextCacheActive),
+                     BoolToString(Token_Status.fContextFetch),
+                     BoolToString(Token_Status.fResultContext),
+                     BoolToString(Token_Status.fProcessingHeld),
+                     BoolToString(Token_Status.fBusy));
+        }
+
+        {
+            GlobalControl97_Context_Status_t Context_Status;
+
+            rc = GlobalControl97_Context_Status_Get(i, &Context_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("Context Status: Err mask: %04x, Available: %d\n"
+                     "Active cntx: %s, next cntx: %s, result cntx: %s"
+                     " Err recov: %s\n",
+                     Context_Status.Error,
+                     Context_Status.AvailableTokenCount,
+                     BoolToString(Context_Status.fActiveContext),
+                     BoolToString(Context_Status.fNextContext),
+                     BoolToString(Context_Status.fResultContext),
+                     BoolToString(Context_Status.fErrorRecovery));
+        }
+
+        {
+            GlobalControl97_Interrupt_Status_t Interrupt_Status;
+
+            rc = GlobalControl97_Interrupt_Status_Get(i, &Interrupt_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("Interrupt Status: input DMA err: %s, output DMA err %s \n"
+                     "pkt proc err: %s, pkt timeout: %s, f a t a l err: %s, "
+                     "PE int out: %s\n"
+                     "inp DMA enable: %s, outp DMA enable %s, "
+                     "pkt proc enable: %s\n"
+                     "pkt timeout enable: %s, f a t a l enable: %s,"
+                     "PE int out enable: %s\n",
+                     BoolToString(Interrupt_Status.fInputDMAError),
+                     BoolToString(Interrupt_Status.fOutputDMAError),
+                     BoolToString(Interrupt_Status.fPacketProcessingError),
+                     BoolToString(Interrupt_Status.fPacketTimeout),
+                     BoolToString(Interrupt_Status.fFatalError),
+                     BoolToString(Interrupt_Status.fPeInterruptOut),
+                     BoolToString(Interrupt_Status.fInputDMAErrorEnabled),
+                     BoolToString(Interrupt_Status.fOutputDMAErrorEnabled),
+                     BoolToString(Interrupt_Status.fPacketProcessingEnabled),
+                     BoolToString(Interrupt_Status.fPacketTimeoutEnabled),
+                     BoolToString(Interrupt_Status.fFatalErrorEnabled),
+                     BoolToString(Interrupt_Status.fPeInterruptOutEnabled));
+        }
+        {
+            GlobalControl97_Output_Transfer_Status_t OutXfer_Status;
+
+            rc = GlobalControl97_OutXfer_Status_Get(i, &OutXfer_Status);
+
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                continue;
+            }
+
+            LOG_CRIT("Output Transfer Status: availabe: %d, "
+                     "min: %d, max: %d, size mask: %d\n",
+                     OutXfer_Status.AvailableWord32Count,
+                     OutXfer_Status.MinTransferWordCount,
+                     OutXfer_Status.MaxTransferWordCount,
+                     OutXfer_Status.TransferSizeMask);
+        }
+        {
+            GlobalControl97_PRNG_Status_t PRNG_Status;
+
+            rc = GlobalControl97_PRNG_Status_Get(i, &PRNG_Status);
+
+            if (rc == GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED)
+            {
+                LOG_CRIT("No PRNG present in EIP-96\n");
+            }
+            else if (rc == GLOBAL_CONTROL_NO_ERROR)
+            {
+                    LOG_CRIT("PRNG Status: busy: %s, res ready: %s\n",
+                             BoolToString(PRNG_Status.fBusy),
+                             BoolToString(PRNG_Status.fResultReady));
+            }
+        }
+    }
+#ifdef ADAPTER_GLOBAL_DBG_STATISTICS
+    {
+        GlobalControl97_Debug_Statistics_t Debug_Statistics;
+
+        rc = GlobalControl97_Debug_Statistics_Get(&Debug_Statistics);
+
+        if (rc != GLOBAL_CONTROL_NO_ERROR)
+        {
+           return;
+        }
+
+        LOG_CRIT("\nInterface DBG Statistics:\n");
+        for (i=0; i<16; i++)
+        {
+            if(Debug_Statistics.Ifc_Packets_In[i] != 0 ||
+               Debug_Statistics.Ifc_Packets_Out[i] != 0)
+            {
+                LOG_CRIT("\t\tInterface #%2u Input pkts=%10u Output pkts=%10u\n",
+                         i,
+                         (unsigned int)Debug_Statistics.Ifc_Packets_In[i],
+                         (unsigned int)Debug_Statistics.Ifc_Packets_Out[i]);
+            }
+        }
+        LOG_CRIT("\nPipe DBG Statistics:\n");
+        for (i=0; i <NofPEs; i++)
+        {
+            LOG_CRIT("\t\tPipe #%2u Total=%10u Data=%10u Cur=%3u Max=%3u\n",
+                     i,
+                     (unsigned int)Debug_Statistics.Pipe_Total_Packets[i],
+                     (unsigned int)Debug_Statistics.Pipe_Data_Count[i],
+                     (unsigned int)Debug_Statistics.Pipe_Current_Packets[i],
+                     (unsigned int)Debug_Statistics.Pipe_Max_Packets[i]);
+        }
+    }
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_Init()
+ *
+ */
+bool
+Adapter_Global_Init(void)
+{
+    unsigned int NofPEs, NofRings, NofLAInterfaces, NofInlineInterfaces;
+    GlobalControl97_Error_t rc;
+    unsigned int i;
+
+    LOG_INFO("\n\t\t Adapter_Global_Init \n");
+
+    // Initialize the device
+    rc = GlobalControl97_Init(false);
+    if (rc != GLOBAL_CONTROL_NO_ERROR)
+    {
+        LOG_CRIT("Adaptar_Global_Init: EIP97 initialization failed\n");
+        return false; // error
+    }
+
+    GlobalControl97_Interfaces_Get(&NofPEs,
+                                   &NofRings,
+                                   &NofLAInterfaces,
+                                   &NofInlineInterfaces);
+
+    // First read the device capabilities
+    {
+        GlobalControl97_Capabilities_t Capabilities;
+
+        rc = GlobalControl97_Capabilities_Get(&Capabilities);
+        if ( rc != GLOBAL_CONTROL_NO_ERROR)
+        {
+            LOG_CRIT("GlobalControl97_Capabilities_Get returned error\n");
+        }
+        else
+        {
+            LOG_CRIT("Global EIP-97 capabilities: %s\n",
+                     Capabilities.szTextDescription);
+        }
+    }
+
+    // Enable the rings for the packet engines
+    {
+        GlobalControl97_Ring_PE_Map_t RingPEMap;
+
+        ZEROINIT(RingPEMap);
+
+        // Enable rings
+        RingPEMap.RingPE_Mask = (1 << (NofRings + NofLAInterfaces + NofInlineInterfaces)) - 1;
+
+        // Set rings priority
+        RingPEMap.RingPrio_Mask = ADAPTER_GLOBAL_EIP97_PRIOMASK;
+
+        for (i=0; i < NofPEs; i++)
+        {
+            rc = GlobalControl97_Configure(i, &RingPEMap);
+            if (rc != GLOBAL_CONTROL_NO_ERROR)
+            {
+                LOG_CRIT("Ring configuration failed for PE %d\n", i);
+                GlobalControl97_UnInit();
+                return false; // error
+            }
+        }
+    }
+
+    {
+        GlobalControl97_PRNG_Status_t PRNG_Status;
+        // Check whether we have a PRNG.
+        rc = GlobalControl97_PRNG_Status_Get(0, &PRNG_Status);
+
+        if (rc != GLOBAL_CONTROL_NO_ERROR && rc != GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED)
+        {
+                return false;
+        }
+
+        if (rc != GLOBAL_CONTROL_ERROR_NOT_IMPLEMENTED)
+        {
+            for (i=0; i < NofPEs; i++)
+            {
+                GlobalControl97_PRNG_Reseed_t PRNG_Reseed;
+
+                PRNG_Reseed.SeedLo = Global_PRNG_Key[0];
+                PRNG_Reseed.SeedHi = Global_PRNG_Key[1];
+                PRNG_Reseed.Key0Lo = Global_PRNG_Key[2];
+                PRNG_Reseed.Key0Hi = Global_PRNG_Key[3];
+                PRNG_Reseed.Key1Lo = Global_PRNG_Key[4];
+                PRNG_Reseed.Key1Hi = Global_PRNG_Key[5];
+                PRNG_Reseed.LFSRLo = Global_PRNG_Key[6];
+                PRNG_Reseed.LFSRHi = Global_PRNG_Key[7];
+
+                rc = GlobalControl97_PRNG_Reseed(i, &PRNG_Reseed);
+
+                if (rc != GLOBAL_CONTROL_NO_ERROR)
+                {
+                    LOG_CRIT("Could not reseed PRNG of PE#%d\n",i);
+                    GlobalControl97_UnInit();
+                    return false; // error
+                }
+            }
+        }
+        else
+        {
+            LOG_CRIT("No PRNG in PEs, skip initialization\n");
+        }
+    }
+
+    Adapter_Global_StatusReport();
+
+    return true; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Global_UnInit()
+ *
+ */
+void
+Adapter_Global_UnInit(void)
+{
+    LOG_INFO("\n\t\t Adapter_Global_UnInit \n");
+
+    Adapter_Global_StatusReport();
+
+    GlobalControl97_UnInit();
+}
+
+
+/* end of file adapter_global_eip97.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init.c
new file mode 100644
index 0000000..ef08853
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init.c
@@ -0,0 +1,413 @@
+/* adapter_init.c
+ *
+ * Adapter module responsible for adapter initialization tasks.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+#include "adapter_interrupts.h" // Adapter_Interrupts_Init,
+                                // Adapter_Interrupts_UnInit
+#endif
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+// Logging API
+#include "log.h"            // LOG_*
+
+// Driver Framework Device API
+#include "device_mgmt.h"    // Device_Initialize, Device_UnInitialize
+#include "device_rw.h"      // Device_Read32, Device_Write32
+
+// Driver Framework DMAResource API
+#include "dmares_mgmt.h"    // DMAResource_Init, DMAResource_UnInit
+
+// Driver Framework C Library API
+#include "clib.h"           // memcpy, ZEROINIT
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"     // bool, true, false
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static bool Adapter_IsInitialized = false;
+
+#ifdef ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+static Device_Handle_t Adapter_Device_BOARDCTRL;
+#endif
+
+static int Device_IRQ;
+
+/*----------------------------------------------------------------------------
+ * Forward declarations
+ */
+
+static int
+AdapterLib_EIP197_Resume(void * p);
+
+#ifdef ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID
+static int
+AdapterLib_EIP197_Suspend(void * p);
+#endif // ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+#ifdef ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID
+static int
+AdapterLib_EIP201_Resume(void * p);
+#endif
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_EIP197_Resume
+ *
+ */
+static int
+AdapterLib_EIP197_Resume(void * p)
+{
+    IDENTIFIER_NOT_USED(p);
+
+    // FPGA board specific functionality
+#ifdef ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+    {
+#ifdef ADAPTER_GLOBAL_FPGA_HW_RESET_ENABLE
+        LOG_INFO("%s: reset FPGA\n", __func__);
+        // Perform HW Reset for the EIP-197 FPGA board
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0);
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0xFFFFFFFF);
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0);
+#endif // ADAPTER_GLOBAL_FPGA_HW_RESET_ENABLE
+    }
+#endif // ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+
+    return 0; // success
+}
+
+
+#ifdef ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID
+/*----------------------------------------------------------------------------
+ * AdapterLib_EIP197_Suspend
+ *
+ */
+static int
+AdapterLib_EIP197_Suspend(void * p)
+{
+    IDENTIFIER_NOT_USED(p);
+
+    // FPGA board specific functionality
+#ifdef ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+    {
+#ifdef ADAPTER_GLOBAL_FPGA_HW_RESET_ENABLE
+        LOG_INFO("%s: reset FPGA\n", __func__);
+        // Perform HW Reset for the EIP-197 FPGA board
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0);
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0xFFFFFFFF);
+        Device_Write32(Adapter_Device_BOARDCTRL, 0x2000, 0);
+#endif // ADAPTER_GLOBAL_FPGA_HW_RESET_ENABLE
+    }
+#endif // ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+
+    return 0; // success
+}
+#endif // ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID
+
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+#ifdef ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID
+/*----------------------------------------------------------------------------
+ * AdapterLib_EIP201_Resume
+ *
+ */
+static int
+AdapterLib_EIP201_Resume(void * p)
+{
+    IDENTIFIER_NOT_USED(p);
+
+    return Adapter_Interrupts_Resume();
+}
+#endif
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Init
+ *
+ * Return Value
+ *     true   Success
+ *     false  Failure (fatal!)
+ */
+bool
+Adapter_Init(void)
+{
+    Device_IRQ = -1;
+
+    if (Adapter_IsInitialized != false)
+    {
+        LOG_WARN("Adapter_Init: Already initialized\n");
+        return true;
+    }
+
+    // trigger first-time initialization of the adapter
+    if (Device_Initialize(&Device_IRQ) < 0)
+        return false;
+
+#ifdef ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+    Adapter_Device_BOARDCTRL = Device_Find("BOARD_CTRL");
+    if (Adapter_Device_BOARDCTRL == NULL)
+    {
+        LOG_CRIT("Adapter_Init: Failed to locate BOARD_CTRL\n");
+        Device_UnInitialize();
+        return false;
+    }
+#endif // ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+
+    if (!DMAResource_Init())
+    {
+        Device_UnInitialize();
+        return false;
+    }
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID,
+                                    AdapterLib_EIP197_Suspend,
+                                    AdapterLib_EIP197_Resume)
+                                                   != RPM_SUCCESS)
+    {
+        DMAResource_UnInit();
+        Device_UnInitialize();
+        return false;
+    }
+
+    AdapterLib_EIP197_Resume(NULL);
+
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID);
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    {
+        int res;
+
+        if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID,
+                                        NULL, // Suspend callback not used
+                                        AdapterLib_EIP201_Resume)
+                                                         != RPM_SUCCESS)
+        {
+            DMAResource_UnInit();
+            Device_UnInitialize();
+            return false;
+        }
+
+        res = Adapter_Interrupts_Init(Device_IRQ);
+
+        (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID);
+
+        if (res < 0)
+        {
+            LOG_CRIT("Adapter_Init: Adapter_Interrupts_Init failed\n");
+            DMAResource_UnInit();
+            Device_UnInitialize();
+            return false;
+        }
+    }
+#endif
+
+    Adapter_IsInitialized = true;
+
+    return true;    // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_UnInit
+ */
+void
+Adapter_UnInit(void)
+{
+    if (!Adapter_IsInitialized)
+    {
+        LOG_WARN("Adapter_UnInit: Adapter is not initialized\n");
+        return;
+    }
+
+    Adapter_IsInitialized = false;
+
+    DMAResource_UnInit();
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    if (RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID,
+                                      true) == RPM_SUCCESS)
+    {
+        Adapter_Interrupts_UnInit(Device_IRQ);
+        (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP201_DEVICE_ID);
+    }
+#endif
+
+    (void)RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID, false);
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_GLOBAL_RPM_EIP197_DEVICE_ID);
+
+    Device_UnInitialize();
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Report_Build_Params
+ */
+void
+Adapter_Report_Build_Params(void)
+{
+    // This function is dependent on config file cs_adapter.h.
+    // Please update this when Config file for Adapter is changed.
+    Log_FormattedMessage("Adapter build configuration of %s:\n",
+        ADAPTER_VERSION_STRING);
+
+#define REPORT_SET(_X) \
+    Log_FormattedMessage("\t" #_X "\n")
+
+#define REPORT_STR(_X) \
+    Log_FormattedMessage("\t" #_X ": %s\n", _X)
+
+#define REPORT_INT(_X) \
+    Log_FormattedMessage("\t" #_X ": %d\n", _X)
+
+#define REPORT_HEX32(_X) \
+    Log_FormattedMessage("\t" #_X ": 0x%08X\n", _X)
+
+#define REPORT_EQ(_X, _Y) \
+    Log_FormattedMessage("\t" #_X " == " #_Y "\n")
+
+#define REPORT_EXPL(_X, _Y) \
+    Log_FormattedMessage("\t" #_X _Y "\n")
+
+    // Adapter PEC
+#ifdef ADAPTER_PEC_DBG
+    REPORT_SET(ADAPTER_PEC_DBG);
+#endif
+
+#ifdef ADAPTER_PEC_STRICT_ARGS
+    REPORT_SET(ADAPTER_PEC_STRICT_ARGS);
+#endif
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    REPORT_SET(ADAPTER_PEC_ENABLE_SCATTERGATHER);
+#endif
+
+#ifdef ADAPTER_PEC_SEPARATE_RINGS
+    REPORT_SET(ADAPTER_PEC_SEPARATE_RINGS);
+#else
+    REPORT_EXPL(ADAPTER_PEC_SEPARATE_RINGS, " is NOT set => Overlapping");
+#endif
+
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+    REPORT_SET(ADAPTER_PEC_ARMRING_ENABLE_SWAP);
+#endif
+
+    REPORT_INT(ADAPTER_PEC_DEVICE_COUNT);
+    REPORT_INT(ADAPTER_PEC_MAX_PACKETS);
+    REPORT_INT(ADAPTER_MAX_PECLOGICDESCR);
+    REPORT_INT(ADAPTER_PEC_MAX_SAS);
+    REPORT_INT(ADAPTER_DESCRIPTORDONETIMEOUT);
+    REPORT_INT(ADAPTER_DESCRIPTORDONECOUNT);
+
+#ifdef ADAPTER_REMOVE_BOUNCEBUFFERS
+    REPORT_EXPL(ADAPTER_REMOVE_BOUNCEBUFFERS, " is SET => Bounce DISABLED");
+#else
+    REPORT_EXPL(ADAPTER_REMOVE_BOUNCEBUFFERS, " is NOT set => Bounce ENABLED");
+#endif
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+    REPORT_EXPL(ADAPTER_EIP202_INTERRUPTS_ENABLE,
+            " is SET => Interrupts ENABLED");
+#else
+    REPORT_EXPL(ADAPTER_EIP202_INTERRUPTS_ENABLE,
+            " is NOT set => Interrupts DISABLED");
+#endif
+
+#ifdef ADAPTER_PCL_ENABLE
+    REPORT_SET(ADAPTER_PCL_ENABLE);
+    REPORT_INT(ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT);
+#endif
+
+#ifdef ADAPTER_64BIT_HOST
+    REPORT_EXPL(ADAPTER_64BIT_HOST,
+                " is SET => addresses are 64-bit");
+#else
+    REPORT_EXPL(ADAPTER_64BIT_HOST,
+                " is NOT set => addresses are 32-bit");
+#endif
+
+#ifdef ADAPTER_64BIT_DEVICE
+    REPORT_EXPL(ADAPTER_64BIT_DEVICE,
+                " is SET => full 64-bit DMA addresses usable");
+#else
+    REPORT_EXPL(ADAPTER_64BIT_DEVICE,
+                " is NOT set => DMA addresses must be below 4GB");
+#endif
+
+#ifdef ADAPTER_DMARESOURCE_BANKS_ENABLE
+    REPORT_SET(ADAPTER_DMARESOURCE_BANKS_ENABLE);
+#endif
+
+    // Adapter Global Classification Control
+#ifdef ADAPTER_CS_TIMER_PRESCALER
+    REPORT_INT(ADAPTER_CS_TIMER_PRESCALER);
+#endif
+
+#ifdef ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE
+    REPORT_SET(ADAPTER_GLOBAL_BOARDCTRL_SUPPORT_ENABLE);
+#endif
+
+    // Log
+    Log_FormattedMessage("Logging:\n");
+
+#if (LOG_SEVERITY_MAX == LOG_SEVERITY_INFO)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_INFO);
+#elif (LOG_SEVERITY_MAX == LOG_SEVERITY_WARNING)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_W_A_R_N_I_N_G);
+#elif (LOG_SEVERITY_MAX == LOG_SEVERITY_CRITICAL)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_CRITICAL);
+#else
+    REPORT_EXPL(LOG_SEVERITY_MAX, " - Unknown (not info/warn/crit)");
+#endif
+
+    // Adapter other
+    Log_FormattedMessage("Other:\n");
+    REPORT_STR(ADAPTER_DRIVER_NAME);
+    REPORT_STR(ADAPTER_LICENSE);
+    REPORT_HEX32(ADAPTER_INTERRUPTS_TRACEFILTER);
+    REPORT_STR(RPM_DEVICE_CAPABILITIES_STR_MACRO);
+}
+
+
+/* end of file adapter_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init_pec.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init_pec.c
new file mode 100644
index 0000000..4bcb88e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_init_pec.c
@@ -0,0 +1,265 @@
+/* adapter_init_pec.c
+ *
+ * Adapter module responsible for Adapter PEC initialization tasks.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Top-level Adapter configuration
+#include "cs_adapter.h"
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+#include "adapter_interrupts.h" // Adapter_Interrupts_Init,
+                                // Adapter_Interrupts_UnInit
+#endif
+
+// Logging API
+#include "log.h"            // LOG_*
+
+// Driver Framework Device API
+#include "device_mgmt.h"    // Device_Initialize, Device_UnInitialize
+#include "device_rw.h"      // Device_Read32, Device_Write32
+
+// Driver Framework DMAResource API
+#include "dmares_mgmt.h"    // DMAResource_Init, DMAResource_UnInit
+
+// Driver Framework C Library API
+#include "clib.h"           // memcpy, ZEROINIT
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"     // bool, true, false
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static bool Adapter_IsInitialized = false;
+static int Device_IRQ;
+
+
+/*----------------------------------------------------------------------------
+ * Forward declarations
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Init
+ *
+ * Return Value
+ *     true   Success
+ *     false  Failure (fatal!)
+ */
+bool
+Adapter_Init(void)
+{
+    Device_IRQ = -1;
+
+    if (Adapter_IsInitialized != false)
+    {
+        LOG_WARN("Adapter_Init: Already initialized\n");
+        return true;
+    }
+
+    // trigger first-time initialization of the adapter
+    if (Device_Initialize(&Device_IRQ) < 0)
+        return false;
+
+    if (!DMAResource_Init())
+    {
+        Device_UnInitialize();
+        return false;
+    }
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    if (Adapter_Interrupts_Init(Device_IRQ) < 0)
+    {
+        LOG_CRIT("Adapter_Init: Adapter_Interrupts_Init failed\n");
+        DMAResource_UnInit();
+        Device_UnInitialize();
+        return false;
+    }
+#endif
+
+    Adapter_IsInitialized = true;
+
+    return true;    // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_UnInit
+ */
+void
+Adapter_UnInit(void)
+{
+    if (!Adapter_IsInitialized)
+    {
+        LOG_WARN("Adapter_UnInit: Adapter is not initialized\n");
+        return;
+    }
+
+    Adapter_IsInitialized = false;
+
+    DMAResource_UnInit();
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    Adapter_Interrupts_UnInit(Device_IRQ);
+#endif
+
+    Device_UnInitialize();
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Report_Build_Params
+ */
+void
+Adapter_Report_Build_Params(void)
+{
+    // This function is dependent on config file cs_adapter.h.
+    // Please update this when Config file for Adapter is changed.
+    Log_FormattedMessage("Adapter build configuration of %s:\n",
+        ADAPTER_VERSION_STRING);
+
+#define REPORT_SET(_X) \
+    Log_FormattedMessage("\t" #_X "\n")
+
+#define REPORT_STR(_X) \
+    Log_FormattedMessage("\t" #_X ": %s\n", _X)
+
+#define REPORT_INT(_X) \
+    Log_FormattedMessage("\t" #_X ": %d\n", _X)
+
+#define REPORT_HEX32(_X) \
+    Log_FormattedMessage("\t" #_X ": 0x%08X\n", _X)
+
+#define REPORT_EQ(_X, _Y) \
+    Log_FormattedMessage("\t" #_X " == " #_Y "\n")
+
+#define REPORT_EXPL(_X, _Y) \
+    Log_FormattedMessage("\t" #_X _Y "\n")
+
+    // Adapter PEC
+#ifdef ADAPTER_PEC_DBG
+    REPORT_SET(ADAPTER_PEC_DBG);
+#endif
+
+#ifdef ADAPTER_PEC_STRICT_ARGS
+    REPORT_SET(ADAPTER_PEC_STRICT_ARGS);
+#endif
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    REPORT_SET(ADAPTER_PEC_ENABLE_SCATTERGATHER);
+#endif
+
+#ifdef ADAPTER_PEC_SEPARATE_RINGS
+    REPORT_SET(ADAPTER_PEC_SEPARATE_RINGS);
+#else
+    REPORT_EXPL(ADAPTER_PEC_SEPARATE_RINGS, " is NOT set => Overlapping");
+#endif
+
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+    REPORT_SET(ADAPTER_PEC_ARMRING_ENABLE_SWAP);
+#endif
+
+    REPORT_INT(ADAPTER_PEC_DEVICE_COUNT);
+    REPORT_INT(ADAPTER_PEC_MAX_PACKETS);
+    REPORT_INT(ADAPTER_MAX_PECLOGICDESCR);
+    REPORT_INT(ADAPTER_PEC_MAX_SAS);
+    REPORT_INT(ADAPTER_DESCRIPTORDONETIMEOUT);
+    REPORT_INT(ADAPTER_DESCRIPTORDONECOUNT);
+
+#ifdef ADAPTER_REMOVE_BOUNCEBUFFERS
+    REPORT_EXPL(ADAPTER_REMOVE_BOUNCEBUFFERS, " is SET => Bounce DISABLED");
+#else
+    REPORT_EXPL(ADAPTER_REMOVE_BOUNCEBUFFERS, " is NOT set => Bounce ENABLED");
+#endif
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+    REPORT_EXPL(ADAPTER_EIP202_INTERRUPTS_ENABLE,
+            " is SET => Interrupts ENABLED");
+#else
+    REPORT_EXPL(ADAPTER_EIP202_INTERRUPTS_ENABLE,
+            " is NOT set => Interrupts DISABLED");
+#endif
+
+#ifdef ADAPTER_PCL_ENABLE
+    REPORT_SET(ADAPTER_PCL_ENABLE);
+    REPORT_INT(ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT);
+#endif
+
+#ifdef ADAPTER_64BIT_HOST
+    REPORT_EXPL(ADAPTER_64BIT_HOST,
+                " is SET => addresses are 64-bit");
+#else
+    REPORT_EXPL(ADAPTER_64BIT_HOST,
+                " is NOT set => addresses are 32-bit");
+#endif
+
+#ifdef ADAPTER_64BIT_DEVICE
+    REPORT_EXPL(ADAPTER_64BIT_DEVICE,
+                " is SET => full 64-bit DMA addresses usable");
+#else
+    REPORT_EXPL(ADAPTER_64BIT_DEVICE,
+                " is NOT set => DMA addresses must be below 4GB");
+#endif
+
+#ifdef ADAPTER_DMARESOURCE_BANKS_ENABLE
+    REPORT_SET(ADAPTER_DMARESOURCE_BANKS_ENABLE);
+#endif
+
+    // Adapter Global Classification Control
+#ifdef ADAPTER_CS_TIMER_PRESCALER
+    REPORT_INT(ADAPTER_CS_TIMER_PRESCALER);
+#endif
+
+    // Log
+    Log_FormattedMessage("Logging:\n");
+
+#if (LOG_SEVERITY_MAX == LOG_SEVERITY_INFO)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_INFO);
+#elif (LOG_SEVERITY_MAX == LOG_SEVERITY_WARNING)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_W_A_R_N_I_N_G);
+#elif (LOG_SEVERITY_MAX == LOG_SEVERITY_CRITICAL)
+    REPORT_EQ(LOG_SEVERITY_MAX, LOG_SEVERITY_CRITICAL);
+#else
+    REPORT_EXPL(LOG_SEVERITY_MAX, " - Unknown (not info/warn/crit)");
+#endif
+
+    // Adapter other
+    Log_FormattedMessage("Other:\n");
+    REPORT_STR(ADAPTER_DRIVER_NAME);
+    REPORT_STR(ADAPTER_LICENSE);
+    REPORT_HEX32(ADAPTER_INTERRUPTS_TRACEFILTER);
+}
+
+
+/* end of file adapter_init_pec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_int_shdevxs.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_int_shdevxs.c
new file mode 100644
index 0000000..d68072b
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_int_shdevxs.c
@@ -0,0 +1,129 @@
+/* adapter_int_shdevxs.c
+ *
+ * Adapter Shared Device Access module responsible for interrupts.
+ * Implementation depends on the Kernel Support Driver.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_interrupts.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"            // bool, IDENTIFIER_NOT_USED
+
+// Kernel support driver
+#include "shdevxs_irq.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_Enable
+ */
+int
+Adapter_Interrupt_Enable(
+        const int nIRQ,
+        const unsigned int Flags)
+{
+    return SHDevXS_IRQ_Enable(nIRQ, Flags);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_Disable
+ *
+ */
+int
+Adapter_Interrupt_Disable(
+        const int nIRQ,
+        const unsigned int Flags)
+{
+    return SHDevXS_IRQ_Disable(nIRQ, Flags);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_SetHandler
+ */
+int
+Adapter_Interrupt_SetHandler(
+        const int nIRQ,
+        Adapter_InterruptHandler_t HandlerFunction)
+{
+    return SHDevXS_IRQ_SetHandler(nIRQ, HandlerFunction);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_Init
+ */
+int
+Adapter_Interrupts_Init(
+        const int nIRQ)
+{
+    int res = SHDevXS_IRQ_Init();
+
+    IDENTIFIER_NOT_USED(nIRQ);
+
+    return res;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_UnInit
+ */
+int
+Adapter_Interrupts_UnInit(
+        const int nIRQ)
+{
+    IDENTIFIER_NOT_USED(nIRQ);
+    return SHDevXS_IRQ_UnInit();
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_Resume
+ */
+int
+Adapter_Interrupts_Resume(void)
+{
+    // Resume AIC devices is done in SHDevXS IRQ module
+    return 0; // success
+}
+
+
+/* end of file adapter_int_shdevxs.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_lock_internal.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_lock_internal.c
new file mode 100644
index 0000000..4b216af
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_lock_internal.c
@@ -0,0 +1,142 @@
+/* adapter_lock_internal.c
+ *
+ * Adapter concurrency (locking) management
+ * Generic implementation
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Adapter locking API
+#include "adapter_lock.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+
+// Adapter Lock Internal API
+#include "adapter_lock_internal.h"
+
+#define TEST_SIZEOF(type, size) \
+    extern int must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+// Check the size of the data structures
+TEST_SIZEOF(Adapter_Lock_CS_Internal_t, sizeof(Adapter_Lock_CS_t));
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_NULL
+ *
+ */
+const Adapter_Lock_t Adapter_Lock_NULL = NULL;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Set
+ */
+void
+Adapter_Lock_CS_Set(
+        Adapter_Lock_CS_t * const CS_p,
+        Adapter_Lock_t Lock)
+{
+    Adapter_Lock_CS_Internal_t * CS_Internal_p =
+                                 (Adapter_Lock_CS_Internal_t*)CS_p;
+
+    if (CS_Internal_p)
+    {
+        // Lock cannot be set while the critical section is entered
+        if (CS_Internal_p->fLocked == false)
+            CS_Internal_p->Lock_p = Lock;
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Get
+ */
+Adapter_Lock_t
+Adapter_Lock_CS_Get(
+        Adapter_Lock_CS_t * const CS_p)
+{
+    Adapter_Lock_CS_Internal_t * CS_Internal_p =
+                                 (Adapter_Lock_CS_Internal_t*)CS_p;
+
+    if (CS_Internal_p)
+        return CS_Internal_p->Lock_p;
+    else
+        return Adapter_Lock_NULL;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Enter
+ */
+bool
+Adapter_Lock_CS_Enter(
+        Adapter_Lock_CS_t * const CS_p)
+{
+    unsigned long Flags;
+    Adapter_Lock_CS_Internal_t * CS_Internal_p =
+                                (Adapter_Lock_CS_Internal_t*)CS_p;
+
+    if (CS_Internal_p == NULL)
+        return false;
+
+    // Enter critical section
+    Adapter_Lock_Acquire(CS_Internal_p->Lock_p, &Flags);
+
+    // Check if critical section is already entered
+    if (CS_Internal_p->fLocked)
+    {
+        Adapter_Lock_Release(CS_Internal_p->Lock_p, &Flags);
+        return false; // CS already entered
+    }
+    else
+        CS_Internal_p->fLocked = true; // success
+
+    // Leave critical section
+    Adapter_Lock_Release(CS_Internal_p->Lock_p, &Flags);
+
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_CS_Leave
+ */
+void
+Adapter_Lock_CS_Leave(
+        Adapter_Lock_CS_t * const CS_p)
+{
+    Adapter_Lock_CS_Internal_t * CS_Internal_p =
+                                (Adapter_Lock_CS_Internal_t*)CS_p;
+
+    if (CS_Internal_p)
+        CS_Internal_p->fLocked = false;
+}
+
+
+/* end of file adapter_lock_internal.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_memxs.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_memxs.c
new file mode 100644
index 0000000..0ec6593
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_memxs.c
@@ -0,0 +1,242 @@
+/* adapter_memxs.c
+ *
+ * Low-level Memory Access API implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// MemXS API
+#include "api_memxs.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_adapter_memxs.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_rw.h"         // Device_Read/Write
+#include "device_mgmt.h"
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcmp
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * MemXS_DeviceAdmin_t
+ *
+ * MemXS device record
+ */
+typedef struct
+{
+    const char *        DevName;
+
+    unsigned int        FirstOfs;
+
+    unsigned int        LastOfs;
+
+    Device_Handle_t     MemXS_Device;
+
+} MemXS_DeviceAdmin_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+// Here is the dependency on the Driver Framework configuration
+// via the MemXS configuration
+#ifndef HWPAL_DEVICES
+#error "Expected HWPAL_DEVICES defined by cs_memxs.h"
+#endif
+
+// Here is the dependency on the Driver Framework configuration
+// via the MemXS configuration
+#undef HWPAL_DEVICE_ADD
+#define HWPAL_DEVICE_ADD(_name, _devnr, _firstofs, _lastofs, _flags) \
+           { _name, _firstofs, _lastofs, NULL }
+
+static MemXS_DeviceAdmin_t MemXS_Devices[] =
+{
+    HWPAL_DEVICES
+};
+
+static const unsigned int MemXS_Device_Count =
+        (sizeof(MemXS_Devices) / sizeof(MemXS_DeviceAdmin_t));
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_NULLHandle
+ *
+ */
+const MemXS_Handle_t MemXS_NULLHandle = { 0 };
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Init
+ */
+bool
+MemXS_Init (void)
+{
+    unsigned int i;
+
+    for(i = 0; i < MemXS_Device_Count; i++)
+    {
+        MemXS_Devices[i].MemXS_Device = NULL;
+
+        MemXS_Devices[i].MemXS_Device =
+                Device_Find (MemXS_Devices[i].DevName);
+
+        if (MemXS_Devices[i].MemXS_Device == NULL)
+        {
+            return false;
+        }
+    } // for
+
+    return true;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * MemXS_Handle_IsSame
+ */
+bool
+MemXS_Handle_IsSame(
+        const MemXS_Handle_t * const Handle1_p,
+        const MemXS_Handle_t * const Handle2_p)
+{
+    return Handle1_p->p == Handle2_p->p;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * MemXS_Device_Count_Get
+ */
+MemXS_Status_t
+MemXS_Device_Count_Get(
+        unsigned int * const DeviceCount_p)
+{
+    if (DeviceCount_p == NULL)
+        return MEMXS_INVALID_PARAMETER;
+
+    *DeviceCount_p = MemXS_Device_Count;
+
+    return MEMXS_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * MemXS_Device_Info_Get
+ */
+MemXS_Status_t
+MemXS_Device_Info_Get(
+        const unsigned int DeviceIndex,
+        MemXS_DevInfo_t * const DeviceInfo_p)
+{
+    if (DeviceInfo_p == NULL)
+        return MEMXS_INVALID_PARAMETER;
+
+    if (DeviceIndex > MemXS_Device_Count)
+        return MEMXS_INVALID_PARAMETER;
+
+    DeviceInfo_p->Index    = DeviceIndex;
+    DeviceInfo_p->Handle.p = MemXS_Devices[DeviceIndex].MemXS_Device;
+    DeviceInfo_p->Name_p   = MemXS_Devices[DeviceIndex].DevName;
+    DeviceInfo_p->FirstOfs = MemXS_Devices[DeviceIndex].FirstOfs;
+    DeviceInfo_p->LastOfs  = MemXS_Devices[DeviceIndex].LastOfs;
+
+    return MEMXS_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Read32
+ */
+uint32_t
+MemXS_Read32(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset)
+{
+    Device_Handle_t Device = (Device_Handle_t)Handle.p;
+
+    return Device_Read32(Device, ByteOffset);
+}
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Write32
+ */
+void
+MemXS_Write32(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const uint32_t Value)
+{
+    Device_Handle_t Device = (Device_Handle_t)Handle.p;
+
+    Device_Write32(Device, ByteOffset, Value);
+}
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Read32Array
+ */
+void
+MemXS_Read32Array(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset,
+        uint32_t * MemoryDst_p,
+        const int Count)
+{
+    Device_Handle_t Device = (Device_Handle_t)Handle.p;
+
+    Device_Read32Array(Device, ByteOffset, MemoryDst_p, Count);
+}
+
+
+/*----------------------------------------------------------------------------
+ * MemXS_Write32Array
+ */
+void
+MemXS_Write32Array(
+        const MemXS_Handle_t Handle,
+        const unsigned int ByteOffset,
+        const uint32_t * MemorySrc_p,
+        const int Count)
+{
+    Device_Handle_t Device = (Device_Handle_t)Handle.p;
+
+    Device_Write32Array(Device, ByteOffset, MemorySrc_p, Count);
+}
+
+
+/* end of file adapter_memxs.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_dtl.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_dtl.c
new file mode 100644
index 0000000..249950a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_dtl.c
@@ -0,0 +1,1051 @@
+/* adapter_pcl_dtl.c
+ *
+ * Packet Classification (PCL) DTL API implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// PCL API
+#include "api_pcl.h"                // PCL_*
+
+// PCL DTL API
+#include "api_pcl_dtl.h"            // PCL_DTL_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_pcl.h"
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Convert address to pair of 32-bit words.
+#include "adapter_addrpair.h"
+
+// Buffer allocation (non-DMA) API
+#include "adapter_alloc.h"
+
+// Adapter PCL Internal API
+#include "adapter_pcl.h"
+
+// Adapter Locking internal API
+#include "adapter_lock.h"       // Adapter_Lock_*
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"
+
+// EIP-207 Driver Library Flow Control DTL API
+#include "eip207_flow_dtl.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_mgmt.h"        // DMAResource management functions
+#include "dmares_rw.h"          // DMAResource buffer access.
+#include "dmares_addr.h"        // DMAResource addr translation functions.
+#include "dmares_buf.h"         // DMAResource buffer allocations
+
+// List API
+#include "list.h"               // List_*
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+// Logging API
+#include "log.h"
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcpy, memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// this implementation requires DMA resource banks
+#ifndef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+#error "Adapter DTL: ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE not defined"
+#endif
+
+// Bit to indicate whether transformr record is large.
+#define ADAPTER_PCL_TR_ISLARGE              BIT_4
+
+
+/*----------------------------------------------------------------------------
+ * Global constants
+ */
+
+
+/*----------------------------------------------------------------------------
+ * PCL_DTL_NULLHandle
+ *
+ */
+const PCL_DTL_Hash_Handle_t PCL_DTL_NULLHandle = { NULL };
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local prototypes
+ */
+
+
+/*-----------------------------------------------------------------------------
+ * PCL API functions implementation
+ *
+ */
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Remove
+ */
+PCL_Status_t
+PCL_Flow_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowHandle_t FlowHandle)
+{
+    PCL_Status_t PCL_Rc = PCL_STATUS_OK;
+    EIP207_Flow_Error_t EIP207_Rc;
+    EIP207_Flow_IOArea_t * ioarea_p;
+    List_Element_t * Element_p = (List_Element_t*)FlowHandle;
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t PCL_Flow_Remove \n");
+
+    // validate input parameters
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
+        FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE ||
+        Element_p == NULL)
+    {
+        return PCL_INVALID_PARAMETER;
+    }
+
+    FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
+
+    if (FlowDescriptor_p == NULL)
+    {
+        LOG_CRIT("PCL_Flow_Remove: failed, invalid flow handle\n");
+        return PCL_INVALID_PARAMETER;
+    }
+
+    // get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+    ioarea_p = Dev_p->EIP207_IOArea_p;
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("PCL_Flow_Add: no device lock, not initialized?\n");
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+    {
+        Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+        return PCL_ERROR;
+    }
+
+    LOG_INFO("\n\t\t EIP207_Flow_DTL_FR_Remove \n");
+
+    EIP207_Rc = EIP207_Flow_DTL_FR_Remove(ioarea_p,
+                                          FlowHashTableId,
+                                          FlowDescriptor_p);
+    if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("PCL_Flow_Remove: failed to remove FR, err=%d\n", EIP207_Rc);
+        PCL_Rc = PCL_ERROR;
+    }
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_Register
+ */
+PCL_Status_t
+PCL_Transform_Register(
+        const DMABuf_Handle_t TransformHandle)
+{
+    unsigned int TR_WordCount;
+    DMAResource_Handle_t DMAHandle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(TransformHandle);
+    DMAResource_Record_t * const Rec_p =
+                                DMAResource_Handle2RecordPtr(DMAHandle);
+
+    LOG_INFO("\n\t PCL_Transform_Register \n");
+
+    // validate parameter
+    if (Rec_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    {
+#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+        uint32_t *TR_p = (uint32_t*)Adapter_DMAResource_HostAddr(DMAHandle);
+
+        Rec_p->fIsLargeTransform = false;
+
+        // Check whether the transform record is large.
+        // Register that in the DMA resource record.
+        if ((*TR_p & ADAPTER_PCL_TR_ISLARGE) != 0)
+        {
+            Rec_p->fIsLargeTransform = true;
+
+            TR_WordCount = EIP207_Flow_DTL_TR_Large_WordCount_Get();
+            *TR_p = *TR_p & ~ADAPTER_PCL_TR_ISLARGE;
+            // Clear that bit in the transform record.
+        }
+        else
+#endif // !ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+        {
+            TR_WordCount = EIP207_Flow_TR_WordCount_Get();
+        }
+    }
+
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+    DMAResource_SwapEndianness_Set(DMAHandle, true);
+#endif
+
+#ifdef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+    if (Rec_p->Props.Bank != ADAPTER_PCL_BANK_TRANSFORM)
+    {
+        LOG_CRIT("PCL Adapter: Invalid bank for Transform\n");
+        return PCL_ERROR;
+    }
+#endif
+
+    if (Rec_p->Props.Size < (sizeof(uint32_t) * TR_WordCount))
+    {
+        LOG_CRIT("PCL_Transform_Register: supplied buffer too small\n");
+        return PCL_ERROR;
+    }
+
+    DMAResource_Write32Array(
+            DMAHandle,
+            0,
+            TR_WordCount,
+            Adapter_DMAResource_HostAddr(DMAHandle));
+
+    DMAResource_PreDMA(DMAHandle, 0, sizeof(uint32_t) * TR_WordCount);
+
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_UnRegister
+ */
+PCL_Status_t
+PCL_Transform_UnRegister(
+        const DMABuf_Handle_t TransformHandle)
+{
+    IDENTIFIER_NOT_USED(TransformHandle.p);
+
+    LOG_INFO("\n\t PCL_Transform_UnRegister \n");
+
+    // Kept for backwards-compatibility, nothing to do here
+
+    return PCL_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * PCL_Transform_Get_ReadOnly
+ */
+PCL_Status_t
+PCL_Transform_Get_ReadOnly(
+        const DMABuf_Handle_t TransformHandle,
+        PCL_TransformParams_t * const TransformParams_p)
+{
+    EIP207_Flow_TR_Dscr_t TransformDescriptor;
+    EIP207_Flow_TR_OutputData_t TransformData;
+    EIP207_Flow_Error_t res;
+    EIP207_Flow_IOArea_t * ioarea_p;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+    DMAResource_Record_t * Rec_p = NULL;
+
+    LOG_INFO("\n\t PCL_Transform_Get_ReadOnly \n");
+
+    if( AdapterPCL_DMABuf_To_TRDscr(
+            TransformHandle, &TransformDescriptor, &Rec_p) != PCL_STATUS_OK)
+        return PCL_ERROR;
+
+    // get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(0);
+    ioarea_p = Dev_p->EIP207_IOArea_p;
+    if (ioarea_p == NULL)
+    {
+        LOG_CRIT("PCL_Transform_Get_ReadOnly: failed, not initialized\n");
+        return PCL_ERROR;
+    }
+
+    {
+#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+        if (Rec_p->fIsLargeTransform)
+        {
+            res = EIP207_Flow_DTL_TR_Large_Read(
+                ioarea_p,
+                0,
+                &TransformDescriptor,
+                &TransformData);
+        }
+        else
+#else
+        IDENTIFIER_NOT_USED(Rec_p);
+#endif // !ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+        {
+            res = EIP207_Flow_TR_Read(
+                ioarea_p,
+                0,
+                &TransformDescriptor,
+                &TransformData);
+        }
+        if (res != EIP207_FLOW_NO_ERROR)
+        {
+            LOG_CRIT("PCL_Transform_Get_ReadOnly: "
+                    "Failed to remove transform record\n");
+            return PCL_ERROR;
+        }
+    }
+
+    TransformParams_p->SequenceNumber   = TransformData.SequenceNumber;
+    TransformParams_p->PacketsCounterLo = TransformData.PacketsCounter;
+    TransformParams_p->PacketsCounterHi = 0;
+    TransformParams_p->OctetsCounterLo  = TransformData.OctetsCounterLo;
+    TransformParams_p->OctetsCounterHi  = TransformData.OctetsCounterHi;
+
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL DTL API functions implementation
+ *
+ */
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Transform_Add
+ */
+PCL_Status_t
+PCL_DTL_Transform_Add(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_DTL_TransformParams_t * const TransformParams,
+        const DMABuf_Handle_t XformDMAHandle,
+        PCL_DTL_Hash_Handle_t * const HashHandle_p)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    PCL_Status_t PCL_Rc2;
+    EIP207_Flow_Error_t EIP207_Rc;
+    EIP207_Flow_IOArea_t * ioarea_p;
+    EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
+    EIP207_Flow_TR_InputData_t TR_inputdata;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+    void * HashList_p = NULL;
+    List_Status_t List_Rc;
+    DMAResource_Record_t * Rec_p = NULL;
+    List_Element_t * Element_p = NULL;
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    // Validate input parameters
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
+        FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE)
+        return PCL_INVALID_PARAMETER;
+
+    // Get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+    ioarea_p = Dev_p->EIP207_IOArea_p;
+
+    if (Dev_p->List_p == NULL)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // Try to add new hash value to Flow Hash Table
+    {
+        unsigned int ListID;
+
+        PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
+        if (PCL_Rc2 != PCL_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed to get free list\n", __func__);
+            goto error_exit;
+        }
+
+        List_Rc = List_RemoveFromTail(ListID, NULL, &Element_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT(
+                "%s: failed to get free element from list\n", __func__);
+            goto error_exit;
+        }
+
+        // Note: Element_p and TR_Dscr_p must be valid by implementation!
+        TR_Dscr_p = (EIP207_Flow_TR_Dscr_t*)Element_p->DataObject_p;
+
+        // Set list element with the transform record descriptor data
+        PCL_Rc2 = AdapterPCL_DMABuf_To_TRDscr(XformDMAHandle, TR_Dscr_p, &Rec_p);
+        if (PCL_Rc2 != PCL_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed, invalid transform\n", __func__);
+            PCL_Rc = PCL_INVALID_PARAMETER;
+            goto error_exit;
+        }
+
+        // Convert transform parameters into EIP-207 transform parameters
+        ZEROINIT(TR_inputdata);
+        TR_inputdata.HashID.Word32[0] = TransformParams->HashID[0];
+        TR_inputdata.HashID.Word32[1] = TransformParams->HashID[1];
+        TR_inputdata.HashID.Word32[2] = TransformParams->HashID[2];
+        TR_inputdata.HashID.Word32[3] = TransformParams->HashID[3];
+
+#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+        TR_inputdata.fLarge = Rec_p->fIsLargeTransform;
+#else
+        TR_inputdata.fLarge = false;
+#endif
+
+        LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Add \n");
+
+        // Add new hash value for this transform record to Flow Hash Table
+        EIP207_Rc = EIP207_Flow_DTL_TR_Add(ioarea_p,
+                                           FlowHashTableId,
+                                           TR_Dscr_p,
+                                           &TR_inputdata);
+        if (EIP207_Rc == EIP207_FLOW_OUT_OF_MEMORY_ERROR)
+        {
+            LOG_CRIT("%s: failed to install transform, "
+                     "out of memory\n", __func__);
+            PCL_Rc = PCL_OUT_OF_MEMORY_ERROR;
+        }
+        else if (EIP207_Rc == EIP207_FLOW_NO_ERROR)
+        {
+            PCL_Rc = PCL_STATUS_OK;
+        }
+        else
+        {
+            LOG_CRIT("%s: failed to install transform, "
+                     "EIP207_Flow_DTL_TR_Add() error %d\n",
+                     __func__,
+                     EIP207_Rc);
+        }
+
+        if (PCL_Rc != PCL_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed to add hash value for transform record\n",
+                     __func__);
+
+            // Return not added element to free list
+            List_Rc = List_AddToHead(ListID, NULL, Element_p);
+            if (List_Rc != LIST_STATUS_OK)
+            {
+                LOG_CRIT("%s: failed to update free list\n", __func__);
+            }
+
+            PCL_Rc = PCL_INVALID_PARAMETER;
+            goto error_exit;
+        }
+    } // Done adding new hash value to Flow Hash Table
+
+    if (Rec_p->Context_p)
+    {
+        // Get list element
+        List_Element_t * TmpElement_p = Rec_p->Context_p;
+
+        // Get hash list that contains all transform record descriptors
+        HashList_p = TmpElement_p->DataObject_p;
+    }
+
+    if(HashList_p == NULL)
+    {
+        // Create hash list for transform record
+
+        List_Element_t * TmpElement_p = NULL;
+
+        // Get a free list from pool of lists
+        List_Rc = List_RemoveFromTail(LIST_DUMMY_LIST_ID,
+                                      Dev_p->List_p,
+                                      &TmpElement_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed to get free element from pool list\n",
+                     __func__);
+            goto error_exit;
+        }
+
+        // Note: TmpElement_p must be valid by implementation!
+        HashList_p = TmpElement_p->DataObject_p;
+
+        // Initialize list instance
+        if (List_Init(LIST_DUMMY_LIST_ID, HashList_p) != LIST_STATUS_OK)
+        {
+            LOG_CRIT("%s: list initialization failed\n", __func__);
+            goto error_exit;
+        }
+
+        // Store list element in the transform record descriptor
+        Rec_p->Context_p = TmpElement_p;
+    } // Created hash list for transform record
+
+    // Add new hash value to list of hash values for this transform record
+    List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID, HashList_p, Element_p);
+    if (List_Rc != LIST_STATUS_OK)
+    {
+        LOG_CRIT("%s: failed to update hash list for transform record\n",
+                 __func__);
+    }
+
+    HashHandle_p->p = Element_p;
+
+error_exit:
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Transform_Remove
+ */
+PCL_Status_t
+PCL_DTL_Transform_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const DMABuf_Handle_t XformDMAHandle)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    PCL_Status_t PCL_Rc2;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+    EIP207_Flow_Error_t EIP207_Rc;
+    EIP207_Flow_IOArea_t * ioarea_p;
+    EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
+    List_Status_t List_Rc;
+    List_Element_t * Element_p;
+    List_Element_t * ListElement_p;
+    unsigned int ListID;
+    void * HashList_p;
+
+    DMAResource_Handle_t DMAHandle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(XformDMAHandle);
+
+    DMAResource_Record_t * Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    // Validate input parameters
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
+        FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE ||
+        Rec_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    // Get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+    ioarea_p = Dev_p->EIP207_IOArea_p;
+
+    if (Dev_p->List_p == NULL)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("%s: no device lock, not initialized?\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
+    if (PCL_Rc2 != PCL_STATUS_OK)
+    {
+        LOG_CRIT("%s: failed to get free list\n", __func__);
+        goto error_exit;
+    }
+
+    // Get list element
+    ListElement_p = Rec_p->Context_p;
+    if (ListElement_p == NULL || ListElement_p->DataObject_p == NULL)
+    {
+        PCL_Rc = PCL_INVALID_PARAMETER;
+        goto error_exit;
+    }
+
+    // Get hash list that contains all transform record descriptors
+    // for this transform
+    HashList_p = ListElement_p->DataObject_p;
+
+    while (HashList_p)
+    {
+        // Get the element from hash list that references record descriptor
+        List_Rc = List_RemoveFromTail(LIST_DUMMY_LIST_ID,
+                                      HashList_p,
+                                      &Element_p);
+        if (List_Rc != LIST_STATUS_OK || Element_p == NULL)
+        {
+            LOG_CRIT(
+                "%s: failed to get element from hash list\n", __func__);
+            goto error_exit;
+        }
+
+        // Retrieve transform record descriptor
+        TR_Dscr_p = Element_p->DataObject_p;
+        if (TR_Dscr_p == NULL)
+        {
+            LOG_CRIT("%s: failed, invalid transform handle\n", __func__);
+            PCL_Rc = PCL_INVALID_PARAMETER;
+            goto error_exit;
+        }
+
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                      RPM_FLAG_SYNC) != RPM_SUCCESS)
+        {
+            PCL_Rc = PCL_ERROR;
+            goto error_exit;
+        }
+
+        LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Remove \n");
+
+        EIP207_Rc = EIP207_Flow_DTL_TR_Remove(ioarea_p,
+                                              FlowHashTableId,
+                                              TR_Dscr_p);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                       RPM_FLAG_ASYNC);
+
+        if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
+        {
+            LOG_CRIT("%s: failed to remove TR, "
+                     "EIP207_Flow_DTL_TR_Remove() error %d\n",
+                    __func__,
+                    EIP207_Rc);
+            // Return element to hash list
+            List_AddToHead(LIST_DUMMY_LIST_ID, HashList_p, Element_p);
+            goto error_exit;
+        }
+
+        {
+            unsigned int Count;
+
+            // Return the element to the free list
+            List_Rc = List_AddToHead(ListID, NULL, Element_p);
+            if (List_Rc != LIST_STATUS_OK)
+            {
+                LOG_CRIT(
+                    "%s: failed to get free element from list\n", __func__);
+                goto error_exit;
+            }
+
+            // Check if transform record has any hash values still referencing it
+            List_GetListElementCount(LIST_DUMMY_LIST_ID, HashList_p, &Count);
+            if (Count == 0)
+            {
+                // Return the element to the free list
+                List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID,
+                                         Dev_p->List_p,
+                                         ListElement_p);
+                if (List_Rc != LIST_STATUS_OK)
+                {
+                    LOG_CRIT("%s: failed to return element to pool list\n",
+                              __func__);
+                    goto error_exit;
+                }
+
+                Rec_p->Context_p = HashList_p = NULL;
+            }
+        }
+    } // while
+
+    PCL_Rc = PCL_STATUS_OK;
+
+error_exit:
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Hash_Remove
+ */
+PCL_Status_t
+PCL_DTL_Hash_Remove(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        PCL_DTL_Hash_Handle_t * const HashHandle_p)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    PCL_Status_t PCL_Rc2;
+    EIP207_Flow_Error_t EIP207_Rc;
+    EIP207_Flow_IOArea_t * ioarea_p;
+    EIP207_Flow_TR_Dscr_t * TR_Dscr_p;
+    List_Element_t * Element_p;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+    DMAResource_Record_t * Rec_p;
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    // Validate input parameters
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||
+        FlowHashTableId >= ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE)
+        return PCL_INVALID_PARAMETER;
+
+    // Get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+    ioarea_p = Dev_p->EIP207_IOArea_p;
+
+    if (Dev_p->List_p == NULL)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("%s: no device lock, not initialized?\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // Retrieve transform record descriptor
+    Element_p = HashHandle_p->p;
+    if (Element_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid hash handle\n", __func__);
+        PCL_Rc = PCL_INVALID_PARAMETER;
+        goto error_exit;
+    }
+
+    TR_Dscr_p = Element_p->DataObject_p;
+    if (TR_Dscr_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid hash handle for transform descriptor\n",
+                 __func__);
+        PCL_Rc = PCL_INVALID_PARAMETER;
+        goto error_exit;
+    }
+
+    Rec_p = DMAResource_Handle2RecordPtr(TR_Dscr_p->DMA_Handle);
+    if (Rec_p == NULL || Rec_p->Context_p == NULL)
+    {
+        LOG_CRIT("%s: failed, invalid hash handle for DMA resource\n",
+                 __func__);
+        PCL_Rc = PCL_INVALID_PARAMETER;
+        goto error_exit;
+    }
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+    {
+        PCL_Rc = PCL_ERROR;
+        goto error_exit;
+    }
+
+    LOG_INFO("\n\t\t EIP207_Flow_DTL_TR_Remove \n");
+
+    EIP207_Rc = EIP207_Flow_DTL_TR_Remove(ioarea_p, FlowHashTableId, TR_Dscr_p);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                   RPM_FLAG_ASYNC);
+
+    if (EIP207_Rc != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("%s: failed to remove TR, "
+                 "EIP207_Flow_DTL_TR_Remove() error %d\n",
+                __func__,
+                EIP207_Rc);
+        goto error_exit;
+    }
+
+    {
+        unsigned int ListID, Count;
+        List_Status_t List_Rc;
+        List_Element_t * ListElement_p = Rec_p->Context_p;
+        void * HashList_p = ListElement_p->DataObject_p;
+
+        // Remove the hash value from the transform record list
+        List_Rc = List_RemoveAnywhere(LIST_DUMMY_LIST_ID,
+                                      HashList_p,
+                                      Element_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed to remove hash from record list\n", __func__);
+        }
+
+        PCL_Rc2 = AdapterPCL_ListID_Get(InterfaceId, &ListID);
+        if (PCL_Rc2 != PCL_STATUS_OK)
+        {
+            LOG_CRIT("%s: failed to get free list\n", __func__);
+            goto error_exit;
+        }
+
+        // Return the element to the free list
+        List_Rc = List_AddToHead(ListID, NULL, Element_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT(
+                "%s: failed to get free element from list\n", __func__);
+            goto error_exit;
+        }
+
+        // Check if transform record has any hash values still referencing it
+        List_GetListElementCount(LIST_DUMMY_LIST_ID, HashList_p, &Count);
+        if (Count == 0)
+        {
+            // Return the element to the free list
+            List_Rc = List_AddToHead(LIST_DUMMY_LIST_ID,
+                                     Dev_p->List_p,
+                                     ListElement_p);
+            if (List_Rc != LIST_STATUS_OK)
+            {
+                LOG_CRIT("%s: failed to return element to pool list\n",
+                          __func__);
+                goto error_exit;
+            }
+
+            Rec_p->Context_p = NULL;
+        }
+    }
+
+    // Invalidate hash handle
+    HashHandle_p->p = NULL;
+
+    PCL_Rc = PCL_STATUS_OK;
+
+error_exit:
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_Init
+ */
+PCL_Status_t
+PCL_DTL_Init(
+        const unsigned int InterfaceId)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    // Validate input parameters.
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
+        return PCL_INVALID_PARAMETER;
+
+    // Get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+
+    if (Dev_p->List_p != NULL)
+    {
+        LOG_CRIT("%s: failed, already initialized\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // Create pool of lists for record descriptors
+    {
+        unsigned int i;
+        void * List_p;
+        List_Element_t * ListElementPool_p;
+        List_Element_t * Element_p;
+        unsigned char * ListPool_p;
+        unsigned int ListInstanceByteCount = List_GetInstanceByteCount();
+
+        // Allocate PCL DTL list instance that will chain other lists
+        List_p = Adapter_Alloc(ListInstanceByteCount);
+        if (List_p == NULL)
+        {
+            LOG_CRIT("%s: list pool allocation failed\n", __func__);
+            goto error_exit;
+        }
+        memset(List_p, 0, ListInstanceByteCount);
+
+        // Initialize PCL DTL list instance
+        if (List_Init(LIST_DUMMY_LIST_ID,
+                      List_p) != LIST_STATUS_OK)
+        {
+            LOG_CRIT("%s: list pool initialization failed\n", __func__);
+            goto error_exit;
+        }
+
+        // Allocate a pool of list elements
+        ListElementPool_p = Adapter_Alloc(sizeof(List_Element_t) *
+                                            ADAPTER_PCL_FLOW_RECORD_COUNT);
+        if (ListElementPool_p == NULL)
+        {
+            LOG_CRIT("%s: pool elements allocation failed\n", __func__);
+            Adapter_Free(List_p);
+            goto error_exit;
+        }
+
+        // Allocate a pool of lists,
+        // one list for one transform record
+        ListPool_p = Adapter_Alloc(ListInstanceByteCount *
+                                           ADAPTER_PCL_FLOW_RECORD_COUNT);
+        if (ListPool_p == NULL)
+        {
+            LOG_CRIT("%s:  pool lists allocation failed\n", __func__);
+            Adapter_Free(List_p);
+            Adapter_Free(ListElementPool_p);
+            goto error_exit;
+        }
+        memset(ListPool_p,
+               0,
+               ListInstanceByteCount * ADAPTER_PCL_FLOW_RECORD_COUNT);
+        Dev_p->ListPool_p = ListPool_p;
+
+        // Populate the pool list with the elements (lists)
+        Element_p = ListElementPool_p;
+        Element_p->DataObject_p = ListPool_p;
+        for (i = 0; i < ADAPTER_PCL_FLOW_RECORD_COUNT; i++)
+        {
+            if (List_AddToHead(LIST_DUMMY_LIST_ID,
+                               List_p,
+                               Element_p) == LIST_STATUS_OK)
+            {
+                if (i + 1 < ADAPTER_PCL_FLOW_RECORD_COUNT)
+                {
+                    Element_p++;
+                    ListPool_p += ListInstanceByteCount;
+                    Element_p->DataObject_p = ListPool_p;
+                }
+            }
+            else
+            {
+                LOG_CRIT("%s: pool list population failed\n", __func__);
+                Dev_p->ListPool_p = NULL;
+                Adapter_Free(List_p);
+                Adapter_Free(ListElementPool_p);
+                Adapter_Free(ListPool_p);
+                goto error_exit;
+            }
+        } // for
+
+        Dev_p->List_p            = List_p;
+        Dev_p->ListElementPool_p = ListElementPool_p;
+
+        PCL_Rc = PCL_STATUS_OK;
+    }  // Created pool of lists for record descriptors
+
+error_exit:
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_DTL_UnInit
+ */
+PCL_Status_t
+PCL_DTL_UnInit(
+        const unsigned int InterfaceId)
+{
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    // Validate input parameters.
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
+        return PCL_INVALID_PARAMETER;
+
+    // Get interface ioarea
+    Dev_p = AdapterPCL_Device_Get(InterfaceId);
+    if (Dev_p->List_p == NULL)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("%s: failed, no device lock, not initialized?\n", __func__);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // pool list data structures
+    Adapter_Free(Dev_p->ListElementPool_p);
+    Adapter_Free(Dev_p->ListPool_p);
+    List_Uninit(LIST_DUMMY_LIST_ID, Dev_p->List_p);
+    Adapter_Free(Dev_p->List_p);
+
+    Dev_p->List_p               = NULL;
+    Dev_p->ListElementPool_p    = NULL;
+    Dev_p->ListPool_p           = NULL;
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+
+    return PCL_STATUS_OK;
+}
+
+
+/* end of file adapter_pcl_dtl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_generic.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_generic.c
new file mode 100644
index 0000000..280d03d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pcl_generic.c
@@ -0,0 +1,1397 @@
+/* adapter_pcl_generic.c
+ *
+ * Packet Classification (PCL) Generic API implementation.
+ *
+ * Notes:
+ * - this implementation does not use SHDEVXS
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// PCL API
+#include "api_pcl.h"            // PCL_DTL_*
+
+// Adapter PCL Internal API
+#include "adapter_pcl.h"        // AdapterPCL_*
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_pcl.h"
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Convert address to pair of 32-bit words.
+#include "adapter_addrpair.h"
+
+// Buffer allocation (non-DMA) API
+#include "adapter_alloc.h"
+
+// sleeping API/
+#include "adapter_sleep.h"
+
+// Adapter Locking internal API
+#include "adapter_lock.h"       // Adapter_Lock_*
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+// Logging API
+#include "log.h"
+
+// Driver Framework Device API
+#include "device_types.h"       // Device_Handle_t
+#include "device_mgmt.h"        // Device_find
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_mgmt.h"        // DMAResource management functions
+#include "dmares_rw.h"          // DMAResource buffer access.
+#include "dmares_addr.h"        // DMAResource addr translation functions.
+#include "dmares_buf.h"         // DMAResource buffer allocations
+
+// List API
+#include "list.h"               // List_*
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcpy, memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t
+
+// EIP-207 Driver Library
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#if ADAPTER_PCL_MAX_DEVICE_DIGITS > 2
+#error "ADAPTER_PCL_MAX_DEVICE_DIGITS > 2 unsupported"
+#endif
+
+// Maximum number of 32-bit words in a 4Gb bank - representable as uint32_t
+#define ADAPTER_PCL_MAX_BANK_WORDS ((uint32_t)((1ULL<<32) / sizeof(uint32_t)))
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static AdapterPCL_Device_Instance_Data_t Dev_Instance [ADAPTER_PCL_MAX_FLUE_DEVICES];
+
+// DMA buffer allocation alignment, in bytes
+static int AdapterPCL_DMA_Alignment_ByteCount =
+                                ADAPTER_DMABUF_ALIGNMENT_INVALID;
+
+// Global lock and critical section for PCL API
+static ADAPTER_LOCK_DEFINE(AdapterPCL_Lock);
+static Adapter_Lock_CS_t AdapterPCL_CS;
+
+// Cached values for RPM device resume operation
+static EIP207_Flow_Address_t EIP207_FlowBaseAddr;
+static EIP207_Flow_Address_t EIP207_TransformBaseAddr;
+static EIP207_Flow_Address_t EIP207_FlowAddr;
+static EIP207_Flow_HT_t EIP207_HT_Params;
+
+
+/*----------------------------------------------------------------------------
+ * Function definitions
+ */
+
+
+/*----------------------------------------------------------------------------
+  AdapterPCLLib_HashTable_Entries_Num_To_Size
+
+  Convert numerical value of number of hashtable entries, to corresponding enum
+
+  number (input)
+    value indicating number of hashtable entries (eg. 32)
+
+  Return:
+      EIP207_Flow_HashTable_Entry_Count_t value representing 'number'
+      or
+      EIP207_FLOW_HASH_TABLE_ENTRIES_MAX+1 indicating error
+
+   Note: implemented using macros to ensure numeric values in step with enums
+ */
+static EIP207_Flow_HashTable_Entry_Count_t
+AdapterPCLLib_HashTable_Entries_Num_To_Size(
+        int number)
+{
+#define HASHTABLE_SIZE_CASE(num) \
+    case (num): return EIP207_FLOW_HASH_TABLE_ENTRIES_##num
+
+    switch (number)
+    {
+        HASHTABLE_SIZE_CASE(32);
+        HASHTABLE_SIZE_CASE(64);
+        HASHTABLE_SIZE_CASE(128);
+        HASHTABLE_SIZE_CASE(256);
+        HASHTABLE_SIZE_CASE(512);
+        HASHTABLE_SIZE_CASE(1024);
+        HASHTABLE_SIZE_CASE(2048);
+        HASHTABLE_SIZE_CASE(4096);
+        HASHTABLE_SIZE_CASE(8192);
+        HASHTABLE_SIZE_CASE(16384);
+        HASHTABLE_SIZE_CASE(32768);
+        HASHTABLE_SIZE_CASE(65536);
+        HASHTABLE_SIZE_CASE(131072);
+        HASHTABLE_SIZE_CASE(262144);
+        HASHTABLE_SIZE_CASE(524288);
+        HASHTABLE_SIZE_CASE(1048576);
+
+        default:
+            return EIP207_FLOW_HASH_TABLE_ENTRIES_MAX + 1;  //invalid value
+    }
+#undef HASHTABLE_SIZE_CASE
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterPCLLib_Device_Find
+ *
+ * Returns device handle corresponding to device interface id (index)
+ * Appends characters corresponding to id number to the device base name.
+ * The base name ADAPTER_PCL_FLUE_DEFAULT_DEVICE_NAME may optionally end in zero '0'.
+ * @note Will handle interface index 0-99
+ */
+static Device_Handle_t
+AdapterPCLLib_Device_Find(unsigned int InterfaceId)
+{
+    char device_name_digit;
+    // base name
+    char device_name[]= ADAPTER_PCL_FLUE_DEFAULT_DEVICE_NAME "\0\0\0\0";
+
+    // string's last char
+    int device_name_digit_index = strlen(device_name) - 1;
+
+    // parameter validation
+    if (InterfaceId > 1 ||  // implementation max
+            InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES ||    // config max
+            InterfaceId > 99   // algorithm max
+            )
+    {
+        return NULL;
+    }
+
+    // use final digit (0) if it's present, otherwise skip to end of base name
+    device_name_digit = device_name[device_name_digit_index];
+    if (device_name_digit != '0')
+    {
+        ++device_name_digit_index;
+    }
+
+    if (InterfaceId >= 10)   // two digit identifier, write tens digit
+    {
+        device_name[device_name_digit_index] = (InterfaceId / 10) + '0';
+        ++device_name_digit_index;
+        InterfaceId %= 10;
+    }
+
+    // write units digit
+    device_name[device_name_digit_index] = InterfaceId + '0';
+
+    // look up actual device
+    return Device_Find(device_name);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_Int_To_Ptr
+ */
+static inline void *
+AdapterPCL_Int_To_Ptr(
+        const unsigned int Value)
+{
+    union Number
+    {
+        void * p;
+        uintptr_t Value;
+    } N;
+
+    N.Value = (uintptr_t)Value;
+
+    return N.p;
+}
+
+
+#ifdef ADAPTER_PCL_RPM_EIP207_DEVICE_ID
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_Resume
+ */
+static int
+AdapterPCL_Resume(void * p)
+{
+    EIP207_Flow_Error_t res;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+    int InterfaceId = *(int *)p;
+
+    // only one hash table in this implementation
+    const unsigned int hashtable_id = 0;
+
+    LOG_INFO("\n\t %s \n", __func__);
+
+    if (InterfaceId < 0 || InterfaceId < ADAPTER_PCL_RPM_EIP207_DEVICE_ID)
+        return -1; // error
+
+    InterfaceId -= ADAPTER_PCL_RPM_EIP207_DEVICE_ID;
+
+    // select current device global instance data, on validated InterfaceId
+    Dev_p = &Dev_Instance[InterfaceId];
+
+#ifdef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+    LOG_INFO("\n\t\t EIP207_Flow_RC_BaseAddr_Set \n");
+
+    // Restore base addresses for flow and transform records
+    res = EIP207_Flow_RC_BaseAddr_Set(Dev_p->EIP207_IOArea_p,
+                                      hashtable_id,
+                                      &EIP207_FlowBaseAddr,
+                                      &EIP207_TransformBaseAddr);
+    if (res != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("%s: set records base address failed, error %d\n",
+                 __func__,
+                 res);
+        return -3;
+    }
+#endif // ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+
+    LOG_INFO("\n\t\t EIP207_Flow_HashTable_Install \n");
+
+    // Restore FLUE hashtable
+    res =  EIP207_Flow_HashTable_Install(Dev_p->EIP207_IOArea_p,
+                                         hashtable_id,
+                                         &EIP207_HT_Params,
+                                         ADAPTER_PCL_ENABLE_FLUE_CACHE,
+                                         false);
+    if (res != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP207_Flow_HashTable_Install() failed, error %d\n",
+                 __func__,
+                 res);
+        return -4;
+    }
+
+    return 0;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------------
+ * Adapter PCL Internal API functions implementation
+ */
+
+/*----------------------------------------------------------------------------
+ * AdapterPCL_DMABuf_To_TRDscr
+ */
+PCL_Status_t
+AdapterPCL_DMABuf_To_TRDscr(
+        const DMABuf_Handle_t TransformHandle,
+        EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+        DMAResource_Record_t ** Rec_pp)
+{
+    DMAResource_Handle_t DMAHandle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(TransformHandle);
+
+    DMAResource_AddrPair_t PhysAddr;
+    DMAResource_Record_t * Rec_p;
+
+    Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+    if (Rec_p == NULL)
+        return PCL_ERROR;
+
+#ifdef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+    if (Rec_p->Props.Bank != ADAPTER_PCL_BANK_TRANSFORM)
+    {
+        LOG_CRIT("PCL Adapter: Invalid bank for Transform\n");
+        return PCL_ERROR;
+    }
+#endif
+
+    if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS, &PhysAddr) < 0)
+    {
+        LOG_CRIT("PCL_Transform: Failed to obtain physical address.\n");
+        return PCL_ERROR;
+    }
+
+    Adapter_AddrToWordPair(PhysAddr.Address_p, 0,
+                           &TR_Dscr_p->DMA_Addr.Addr,
+                           &TR_Dscr_p->DMA_Addr.UpperAddr);
+
+    TR_Dscr_p->DMA_Handle = DMAHandle;
+
+    *Rec_pp = Rec_p;
+
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_Device_Get
+ */
+AdapterPCL_Device_Instance_Data_t *
+AdapterPCL_Device_Get(
+        const unsigned int InterfaceId)
+{
+    return &Dev_Instance[InterfaceId];
+}
+
+
+/*-----------------------------------------------------------------------------
+ * AdapterPCL_ListID_Get
+ */
+PCL_Status_t
+AdapterPCL_ListID_Get(
+        const unsigned int InterfaceId,
+        unsigned int * const ListID_p)
+{
+    // validate parameter
+    if (ListID_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    *ListID_p = Dev_Instance[InterfaceId].FreeListID;
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Adapter PCL API functions implementation
+ */
+
+/*----------------------------------------------------------------------------
+ * PCL_Init
+ */
+PCL_Status_t
+PCL_Init(
+        const unsigned int InterfaceId,
+        const unsigned int NofFlowHashTables)
+{
+    EIP207_Flow_Error_t res;
+    Device_Handle_t EIP207_Device;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    unsigned int ioarea_size_bytes;
+    unsigned int descr_total_size_bytes;
+    unsigned int hashtable_entry_size_words, hashtable_total_size_words;
+
+    List_Element_t * ElementPool_p = NULL;
+    unsigned char * RecDscrPool_p = NULL;
+    EIP207_Flow_IOArea_t * ioarea_p = NULL;
+    void * descr_area_ptr = NULL;
+
+    // includes overflow records
+    const unsigned int total_hasharea_element_count =
+                            (ADAPTER_PCL_FLOW_HASH_OVERFLOW_COUNT +
+                                    ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT);
+
+    DMAResource_Handle_t hashtable_dma_handle = NULL;
+
+    // only one hash table in this implementation
+    const unsigned int hashtable_id = 0;
+
+    LOG_INFO("\n\t PCL_Init \n");
+
+    // check number of hash tables against implementation & config limits
+    if (NofFlowHashTables == 0 ||   // validity
+        NofFlowHashTables > 1 || // implementation limit
+        NofFlowHashTables > ADAPTER_CS_MAX_NOF_FLOW_HASH_TABLES_TO_USE)
+    {
+        LOG_CRIT("PCL_Init: Invalid number (%d) of hash tables\n",
+                 NofFlowHashTables);
+        return PCL_INVALID_PARAMETER;
+    }
+
+    Adapter_Lock_CS_Set(&AdapterPCL_CS, &AdapterPCL_Lock);
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPCL_CS))
+        return PCL_STATUS_BUSY;
+
+    // select current device global instance data, on validated InterfaceId
+    Dev_p = &Dev_Instance[InterfaceId];
+
+    // state consistency check
+    if (Dev_p->PCL_IsInitialized)
+    {
+        LOG_CRIT("PCL_Init: Already initialized\n");
+        Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+        return PCL_ERROR;
+    }
+
+    // Initialize instance variables to 0/NULL defaults
+    ZEROINIT(*Dev_p);
+
+    // Allocate device lock
+    Dev_p->AdapterPCL_DevLock = Adapter_Lock_Alloc();
+    if (Dev_p->AdapterPCL_DevLock == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("PCL_Init: PutLock allocation failed\n");
+        Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+        return PCL_OUT_OF_MEMORY_ERROR;
+    }
+    Adapter_Lock_CS_Set(&Dev_p->AdapterPCL_DevCS,
+                         Dev_p->AdapterPCL_DevLock);
+
+    // identify device, check InterfaceId
+    EIP207_Device = AdapterPCLLib_Device_Find(InterfaceId);
+    if (EIP207_Device == NULL)
+    {
+        LOG_CRIT("PCL_Init: Cannot find EIP-207 device, id=%d\n", InterfaceId);
+        goto error_exit;
+    }
+
+    // Get DMA buffer allocation alignment
+    AdapterPCL_DMA_Alignment_ByteCount = Adapter_DMAResource_Alignment_Get();
+    if (AdapterPCL_DMA_Alignment_ByteCount == ADAPTER_DMABUF_ALIGNMENT_INVALID)
+    {
+#if ADAPTER_PCL_DMA_ALIGNMENT_BYTE_COUNT == 0
+        LOG_CRIT("PCL_Init: Failed to get DMA alignment\n");
+        goto error_exit;
+#else
+        AdapterPCL_DMA_Alignment_ByteCount =
+                                ADAPTER_PCL_DMA_ALIGNMENT_BYTE_COUNT;
+#endif
+    }
+
+    // allocate IOArea non-DMA memory
+    ioarea_size_bytes = EIP207_Flow_IOArea_ByteCount_Get();
+    ioarea_p = Adapter_Alloc(ioarea_size_bytes);
+
+    if (ioarea_p == NULL)
+    {
+        LOG_CRIT("PCL_Init: Cannot allocate IOArea\n");
+        goto error_exit;
+    }
+
+    // store value for global use
+    Dev_p->EIP207_IOArea_p = ioarea_p;
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                    0, // No suspend callback is used
+                                    AdapterPCL_Resume) != RPM_SUCCESS)
+        goto error_exit;
+
+    LOG_INFO("\n\t\t EIP207_Flow_Init \n");
+
+    // hand IOArea memory to driver
+    res = EIP207_Flow_Init(Dev_p->EIP207_IOArea_p,
+                           EIP207_Device);
+    if (res != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("PCL_Init: EIP207_Flow_Init() failed\n");
+        goto fail;  // exit which frees allocated resources
+    }
+
+#ifdef ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+    {
+        unsigned int RecordWordCount;
+
+        RecordWordCount = EIP207_Flow_TR_WordCount_Get();
+
+        if (RecordWordCount * sizeof(uint32_t) >
+                ADAPTER_TRANSFORM_RECORD_BYTE_COUNT)
+        {
+            LOG_CRIT("PCL_Init: Bad Record size in transform bank, "
+                     "is %d, at least %d required\n",
+                     (int)(ADAPTER_TRANSFORM_RECORD_BYTE_COUNT *
+                               sizeof(uint32_t)),
+                     RecordWordCount);
+            goto fail;  // exit which frees allocated resources
+        }
+
+        RecordWordCount = EIP207_Flow_FR_WordCount_Get();
+
+        if (RecordWordCount * sizeof(uint32_t) >
+                           ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT)
+        {
+            LOG_CRIT("PCL_Init: Bad Record size in flow bank, "
+                     "is %d, at least %d required\n",
+                     (int)(ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT *
+                               sizeof(uint32_t)),
+                     RecordWordCount);
+            goto fail;  // exit which frees allocated resources
+        }
+    }
+
+    { // Set the SA pool base address.
+        int dmares;
+        DMAResource_Handle_t DMAHandle;
+        DMAResource_Properties_t DMAProperties;
+        DMAResource_AddrPair_t DMAAddr;
+
+        ZEROINIT(EIP207_FlowBaseAddr);
+        ZEROINIT(EIP207_TransformBaseAddr);
+
+        // Perform a full-bank allocation in transform bank to obtain the bank base
+        // address.
+        {
+            DMAProperties.Alignment = AdapterPCL_DMA_Alignment_ByteCount;
+            DMAProperties.Bank      = ADAPTER_PCL_BANK_TRANSFORM;
+            DMAProperties.fCached   = false;
+            DMAProperties.Size      = ADAPTER_TRANSFORM_RECORD_COUNT *
+                                          ADAPTER_TRANSFORM_RECORD_BYTE_COUNT;
+            dmares = DMAResource_Alloc(DMAProperties,
+                                       &DMAAddr,
+                                       &DMAHandle);
+            if (dmares != 0)
+            {
+                LOG_CRIT(
+                        "PCL_Init: allocate transforms base address failed\n");
+                goto fail;  // exit which frees allocated resources
+            }
+
+            // Derive the physical address from the DMA resource.
+            if (DMAResource_Translate(DMAHandle,
+                                      DMARES_DOMAIN_BUS,
+                                      &DMAAddr)             < 0)
+            {
+                DMAResource_Release(DMAHandle);
+                LOG_CRIT(
+                      "PCL_Init: translate transforms base address failed\n");
+                goto fail;  // exit which frees allocated resources
+            }
+
+            Adapter_AddrToWordPair(DMAAddr.Address_p,
+                                   0,
+                                   &EIP207_TransformBaseAddr.Addr,
+                                   &EIP207_TransformBaseAddr.UpperAddr);
+
+            // Release the DMA resource
+            DMAResource_Release(DMAHandle);
+        }
+
+        // Perform a size 0 allocation in flow bank to obtain the bank base
+        // address.
+        DMAProperties.Alignment = AdapterPCL_DMA_Alignment_ByteCount;
+        DMAProperties.Bank      = ADAPTER_PCL_BANK_FLOW;
+        DMAProperties.fCached   = false;
+        DMAProperties.Size      = ADAPTER_PCL_FLOW_RECORD_COUNT *
+                                          ADAPTER_PCL_FLOW_RECORD_BYTE_COUNT;
+        dmares = DMAResource_Alloc(DMAProperties,
+                                   &DMAAddr,
+                                   &DMAHandle);
+        if (dmares != 0)
+        {
+            LOG_CRIT("PCL_Init: allocate flow base address failed\n");
+            goto fail;  // exit which frees allocated resources
+        }
+
+        // Derive the physical address from the DMA resource.
+        if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS, &DMAAddr) < 0)
+        {
+            DMAResource_Release(DMAHandle);
+            LOG_CRIT("PCL_Init: translate flow base address failed\n");
+            goto fail;  // exit which frees allocated resources
+        }
+
+        Adapter_AddrToWordPair(DMAAddr.Address_p, 0,
+                               &EIP207_FlowBaseAddr.Addr,
+                               &EIP207_FlowBaseAddr.UpperAddr);
+
+        // Release the DMA resource - handle to zero-size request.
+        DMAResource_Release(DMAHandle);
+
+        LOG_INFO("\n\t\t EIP207_Flow_RC_BaseAddr_Set \n");
+
+        // set base addresses for flow and transform records
+        res = EIP207_Flow_RC_BaseAddr_Set(
+                ioarea_p,
+                hashtable_id,
+                &EIP207_FlowBaseAddr,
+                &EIP207_TransformBaseAddr);
+        if (res != EIP207_FLOW_NO_ERROR)
+        {
+            LOG_CRIT("PCL_Init: set records base address failed\n");
+            goto fail;  // exit which frees allocated resources
+        }
+
+    }
+#endif // ADAPTER_PCL_DMARESOURCE_BANKS_ENABLE
+
+    // Install Hashtable:
+    // - calculate amount of required descriptor memory & allocate it
+    // - calculate amount of required DMA-safe hashtable+overflow memory &
+    //   allocate it
+    // - fill in struct for HT install, call install function
+
+    // descriptor memory
+    descr_total_size_bytes = EIP207_Flow_HTE_Dscr_ByteCount_Get() *
+                                               total_hasharea_element_count;
+
+    descr_area_ptr = Adapter_Alloc(descr_total_size_bytes);
+    if (descr_area_ptr == NULL)
+    {
+        LOG_CRIT("PCL_Init: Cannot allocate descriptor area\n");
+        goto fail;  // exit which frees allocated resources
+    }
+
+    // store value for global use
+    Dev_p->EIP207_Descriptor_Area_p = descr_area_ptr;
+
+    // get required memory size for hash table
+    // = (hash table size + overflow entries)*bucket size
+    hashtable_entry_size_words = EIP207_Flow_HT_Entry_WordCount_Get();
+    hashtable_total_size_words =
+            hashtable_entry_size_words * total_hasharea_element_count;
+
+    // check total size of hashtable region (lookup + overflow)
+    // would not exceed a 32-bit addressable bank of 4GB
+    if (hashtable_total_size_words >= ADAPTER_PCL_MAX_BANK_WORDS)
+    {
+        LOG_CRIT("PCL_Init: Too many hashtable lookup elements for bank\n");
+        goto fail;  // exit which frees allocated resources
+    }
+
+    // get DMA-safe memory for hashtable in appropriate bank
+    {
+        DMAResource_Properties_t TableProperties;
+        DMAResource_AddrPair_t TableHostAddr;
+        DMAResource_AddrPair_t PhysAddr;
+        int dmares;
+
+        // required DMA buffer properties
+        TableProperties.Alignment = AdapterPCL_DMA_Alignment_ByteCount;
+        // Hash table DMA bank
+        TableProperties.Bank      = ADAPTER_PCL_BANK_FLOWTABLE;
+        TableProperties.fCached   = false;
+        // Check if this does not exceed 4 GB, do it somewhere above
+        // size in bytes
+        TableProperties.Size      = hashtable_total_size_words *
+                                                        sizeof(uint32_t);
+
+        // Perform a full-bank allocation in flow table bank to obtain
+        // the bank base address.
+        dmares = DMAResource_Alloc(TableProperties,
+                                   &TableHostAddr,
+                                   &hashtable_dma_handle);
+
+#ifdef ADAPTER_PCL_ENABLE_SWAP
+        DMAResource_SwapEndianness_Set(hashtable_dma_handle, true);
+#endif
+        if (dmares != 0)
+        {
+            LOG_CRIT("PCL_Init: Failed to allocate flow hash table\n");
+            goto fail;  // exit which frees allocated resources
+        }
+
+        // get physical address from handle
+        if (DMAResource_Translate(hashtable_dma_handle,
+                                  DMARES_DOMAIN_BUS,
+                                  &PhysAddr) < 0)
+        {
+            LOG_CRIT("PCL_Init: Failed to obtain physical address.\n");
+            goto fail;  // exit which frees allocated resources
+        }
+
+        ZEROINIT(EIP207_FlowAddr);
+
+        // physical address as upper and lower (EIP207_Flow_Address_t)
+        Adapter_AddrToWordPair(PhysAddr.Address_p, 0,
+                               &EIP207_FlowAddr.Addr,
+                               &EIP207_FlowAddr.UpperAddr);
+
+        // fill in FLUE hashtable descriptor fields
+        ZEROINIT(EIP207_HT_Params);
+
+        // handle
+        EIP207_HT_Params.HT_DMA_Handle    = hashtable_dma_handle;
+
+        // translated addr
+        EIP207_HT_Params.HT_DMA_Address_p = &EIP207_FlowAddr;
+
+        // Convert numerical value to enum
+        EIP207_HT_Params.HT_TableSize     =
+                            AdapterPCLLib_HashTable_Entries_Num_To_Size(
+                                         ADAPTER_PCL_FLOW_HASH_ENTRIES_COUNT);
+        EIP207_HT_Params.DT_p             = descr_area_ptr;
+
+        // hash table plus overflow
+        EIP207_HT_Params.DT_EntryCount    = total_hasharea_element_count;
+    }
+
+    LOG_INFO("\n\t\t EIP207_Flow_HashTable_Install \n");
+
+    // install FLUE hashtable
+    res =  EIP207_Flow_HashTable_Install(ioarea_p,
+                                         hashtable_id,
+                                         &EIP207_HT_Params,
+                                         ADAPTER_PCL_ENABLE_FLUE_CACHE,
+                                         true);
+    if (res != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("PCL_Init: EIP207_Flow_HashTable_Install failed\n");
+        goto fail;  // exit which frees allocated resources
+    }
+
+    // Initialize the free list of record descriptors
+    {
+        unsigned int i;
+        List_Element_t * Element_p;
+        unsigned char * RecDscr_p;
+        unsigned int RecordByteCount = MAX(EIP207_Flow_FR_Dscr_ByteCount_Get(),
+            EIP207_Flow_TR_Dscr_ByteCount_Get());
+
+        // Set the free list ID
+        Dev_p->FreeListID = ADAPTER_PCL_LIST_ID_OFFSET + InterfaceId;
+
+        // Allocate a pool of list elements
+        ElementPool_p = Adapter_Alloc(sizeof(List_Element_t) *
+                                        total_hasharea_element_count);
+        if (ElementPool_p == NULL)
+        {
+            LOG_CRIT("PCL_Init: free list allocation failed\n");
+            goto fail;
+        }
+
+        if (List_Init(Dev_p->FreeListID, NULL) != LIST_STATUS_OK)
+        {
+            LOG_CRIT("PCL_Init: free list initialization failed\n");
+            goto fail;
+        }
+
+        // Allocate a pool of record descriptors
+        RecDscrPool_p = Adapter_Alloc( RecordByteCount *
+                                            total_hasharea_element_count);
+        if (RecDscrPool_p == NULL)
+        {
+            LOG_CRIT("PCL_Init: record descriptor allocation failed\n");
+            goto fail;
+        }
+
+        // Populate the free list with the elements (record descriptors)
+        Element_p = ElementPool_p;
+        Element_p->DataObject_p = RecDscr_p = RecDscrPool_p;
+        for(i = 0; i < total_hasharea_element_count; i++)
+        {
+            if (List_AddToHead(Dev_p->FreeListID,
+                               NULL,
+                               Element_p) == LIST_STATUS_OK)
+            {
+                if (i < total_hasharea_element_count - 1)
+                {
+                    Element_p++;
+                    RecDscr_p += RecordByteCount;
+                    Element_p->DataObject_p = RecDscr_p;
+                }
+            }
+            else
+            {
+                LOG_CRIT("PCL_Init: free list population failed\n");
+                goto fail;
+            }
+        }
+
+        Dev_p->RecDscrPool_p = RecDscrPool_p;
+        Dev_p->ElementPool_p = ElementPool_p;
+    }  // Record descriptors free list initialized
+
+    // set remaining instance variables, on success
+    Dev_p->EIP207_Hashtable_DMA_Handle = hashtable_dma_handle;
+    Dev_p->PCL_IsInitialized = true;
+
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId);
+
+    Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+
+    return PCL_STATUS_OK;
+
+fail:
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId);
+
+    // free List data structures
+    Adapter_Free(ElementPool_p);
+    Adapter_Free(RecDscrPool_p);
+    List_Uninit(Dev_p->FreeListID, NULL);
+
+    // free memory areas and DMA-safe memory
+    Adapter_Free(Dev_p->EIP207_IOArea_p);
+    Adapter_Free(Dev_p->EIP207_Descriptor_Area_p);
+    if (hashtable_dma_handle != NULL)
+        DMAResource_Release(hashtable_dma_handle);
+
+error_exit:
+    Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+
+    return PCL_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PCL_UnInit
+ */
+PCL_Status_t
+PCL_UnInit(
+        const unsigned int InterfaceId)
+{
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t PCL_UnInit \n");
+
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
+    {
+        return PCL_INVALID_PARAMETER;
+    }
+
+    Adapter_Lock_CS_Set(&AdapterPCL_CS, &AdapterPCL_Lock);
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPCL_CS))
+        return PCL_STATUS_BUSY;
+
+    // select current device instance data, on validated InterfaceId
+    Dev_p = &Dev_Instance[InterfaceId];
+
+    if (!Dev_p->PCL_IsInitialized)
+    {
+        LOG_CRIT("PCL_UnInit: Not initialized\n");
+        Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+    {
+        Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+        Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+        return PCL_STATUS_BUSY;
+    }
+
+    if (RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId,
+                                      false) != RPM_SUCCESS)
+    {
+        Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+        Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+        return PCL_ERROR;
+    }
+
+    // free List data structures
+    Adapter_Free(Dev_p->ElementPool_p);
+    Adapter_Free(Dev_p->RecDscrPool_p);
+    List_Uninit(Dev_p->FreeListID, NULL);
+
+    // pool list data structures
+    Adapter_Free(Dev_p->ListElementPool_p);
+    Adapter_Free(Dev_p->ListPool_p);
+    if (Dev_p->List_p)
+    {
+        List_Uninit(LIST_DUMMY_LIST_ID, Dev_p->List_p);
+        Dev_p->List_p = NULL;
+    }
+
+    // free memory areas and DMA-safe memory
+    Adapter_Free(Dev_p->EIP207_IOArea_p);
+    Adapter_Free(Dev_p->EIP207_Descriptor_Area_p);
+    DMAResource_Release(Dev_p->EIP207_Hashtable_DMA_Handle);
+
+    // reset globals
+    Dev_p->EIP207_IOArea_p              = NULL;
+    Dev_p->EIP207_Hashtable_DMA_Handle  = NULL;
+    Dev_p->EIP207_Descriptor_Area_p     = NULL;
+    Dev_p->RecDscrPool_p                = NULL;
+    Dev_p->ElementPool_p                = NULL;
+
+    Dev_p->PCL_IsInitialized = false;
+
+    AdapterPCL_DMA_Alignment_ByteCount = ADAPTER_DMABUF_ALIGNMENT_INVALID;
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+
+    // Free device lock
+    Adapter_Lock_Free(Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS));
+    Adapter_Lock_CS_Set(&Dev_p->AdapterPCL_DevCS, Adapter_Lock_NULL);
+
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID + InterfaceId);
+
+    Adapter_Lock_CS_Leave(&AdapterPCL_CS);
+
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_DMABuf_Handle_Get
+ */
+PCL_Status_t
+PCL_Flow_DMABuf_Handle_Get(
+        const PCL_FlowHandle_t FlowHandle,
+        DMABuf_Handle_t * const DMAHandle_p)
+{
+    DMAResource_Handle_t DMARes_Handle;
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    List_Element_t * Element_p = (List_Element_t*)FlowHandle;
+
+    LOG_INFO("\n\t PCL_Flow_DMABuf_Handle_Get \n");
+
+    if (DMAHandle_p == NULL ||
+        Element_p == NULL)
+    {
+        LOG_CRIT("PCL_Flow_DMABuf_Handle_Get: failed, invalid DMABuf handle or Flow Handle\n");
+        return PCL_INVALID_PARAMETER;
+    }
+
+    FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
+
+    if (FlowDescriptor_p == NULL)
+    {
+        LOG_CRIT("PCL_Flow_DMABuf_Handle_Get: failed, invalid flow handle\n");
+        return PCL_INVALID_PARAMETER;
+    }
+
+    DMARes_Handle = FlowDescriptor_p->DMA_Handle;
+
+    *DMAHandle_p = Adapter_DMAResource_Handle2DMABufHandle(DMARes_Handle);
+
+    return PCL_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PCL_Flow_Hash
+ */
+PCL_Status_t
+PCL_Flow_Hash(
+        const PCL_SelectorParams_t * const SelectorParams,
+        uint32_t * FlowID_Word32ArrayOf4)
+{
+    EIP207_Flow_SelectorParams_t EIP207_SelectorParams;
+    EIP207_Flow_ID_t FlowID;
+    EIP207_Flow_Error_t res;
+    const unsigned int hashtable_id = 0;    // implementation limit
+
+    LOG_INFO("\n\t PCL_Flow_Hash \n");
+
+    if (SelectorParams == NULL || FlowID_Word32ArrayOf4 == NULL)
+        return PCL_ERROR;
+
+    ZEROINIT(EIP207_SelectorParams);
+    ZEROINIT(FlowID);
+
+    EIP207_SelectorParams.Flags   = SelectorParams->flags;
+    EIP207_SelectorParams.SrcIp_p = SelectorParams->SrcIp;
+    EIP207_SelectorParams.DstIp_p = SelectorParams->DstIp;
+    EIP207_SelectorParams.IpProto = SelectorParams->IpProto;
+    EIP207_SelectorParams.SrcPort = SelectorParams->SrcPort;
+    EIP207_SelectorParams.DstPort = SelectorParams->DstPort;
+    EIP207_SelectorParams.SPI     = SelectorParams->spi;
+    EIP207_SelectorParams.Epoch  = SelectorParams->epoch;
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return PCL_ERROR;
+
+    LOG_INFO("\n\t\t EIP207_Flow_ID_Compute \n");
+
+    res = EIP207_Flow_ID_Compute(
+            Dev_Instance[hashtable_id].EIP207_IOArea_p,
+            hashtable_id,
+            &EIP207_SelectorParams,
+            &FlowID);
+
+    // Note: only one EIP-207 hash table is supported!
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PCL_RPM_EIP207_DEVICE_ID,
+                                   RPM_FLAG_ASYNC);
+
+    if (res != EIP207_FLOW_NO_ERROR)
+    {
+        LOG_CRIT("PCL_Flow_Hash: operation failed\n");
+        return PCL_ERROR;
+    }
+
+    FlowID_Word32ArrayOf4[0] = FlowID.Word32[0];
+    FlowID_Word32ArrayOf4[1] = FlowID.Word32[1];
+    FlowID_Word32ArrayOf4[2] = FlowID.Word32[2];
+    FlowID_Word32ArrayOf4[3] = FlowID.Word32[3];
+
+    return PCL_STATUS_OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Alloc
+ */
+PCL_Status_t
+PCL_Flow_Alloc(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        PCL_FlowHandle_t * const FlowHandle_p)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    DMAResource_Handle_t DMAHandle;
+    DMAResource_Properties_t DMAProperties;
+    DMAResource_AddrPair_t HostAddr;
+    DMAResource_AddrPair_t PhysAddr;
+    int dmares;
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    unsigned int FR_WordCount;
+    List_Element_t * Element_p;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t PCL_Flow_Alloc \n");
+
+    IDENTIFIER_NOT_USED(FlowHashTableId);
+
+    // validate interface id
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
+        return PCL_INVALID_PARAMETER;
+
+    Dev_p = &Dev_Instance[InterfaceId];
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("PCL_Flow_Alloc: no device lock, not initialized?\n");
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // select current device instance data, on validated InterfaceId
+    if (!Dev_p->PCL_IsInitialized)
+    {
+        LOG_CRIT("PCL_Flow_Alloc: Not initialized\n");
+        goto error_exit;
+    }
+
+    *FlowHandle_p = NULL;
+
+    LOG_INFO("\n\t\t EIP207_Flow_FR_WordCount_Get \n");
+
+    // Get the required size of the DMA buffer for the flow record.
+    FR_WordCount = EIP207_Flow_FR_WordCount_Get();
+
+    // Allocate a buffer for the flow record (DMA).
+    DMAProperties.Alignment = AdapterPCL_DMA_Alignment_ByteCount;
+    DMAProperties.Bank      = ADAPTER_PCL_BANK_FLOW;
+    DMAProperties.fCached   = false;
+    DMAProperties.Size      = 4 * FR_WordCount;
+
+    dmares = DMAResource_Alloc(DMAProperties, &HostAddr, &DMAHandle);
+    if (dmares != 0)
+    {
+        LOG_CRIT("PCL_Flow_Alloc: could not allocate buffer\n");
+        goto error_exit;
+    }
+
+#ifdef ADAPTER_PCL_ENABLE_SWAP
+    DMAResource_SwapEndianness_Set(DMAHandle, true);
+#endif
+
+    // Get a record descriptor from the free list
+    {
+        List_Status_t List_Rc =
+                List_RemoveFromTail(Dev_p->FreeListID,
+                                    NULL,
+                                    &Element_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT("PCL_Flow_Alloc: failed to allocate record\n");
+            goto error_exit;
+        }
+
+        // Get the flow record descriptor place-holder from the list element
+        FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t*)Element_p->DataObject_p;
+        if (FlowDescriptor_p == NULL)
+        {
+            LOG_CRIT("PCL_Flow_Alloc: failed to get record descriptor\n");
+            goto error_exit;
+        }
+    }
+
+    // Fill in the descriptor.
+    FlowDescriptor_p->DMA_Handle = DMAHandle;
+
+    if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS, &PhysAddr) < 0)
+    {
+        LOG_CRIT("PCL_FlowAlloc: Failed to obtain physical address.\n");
+        DMAResource_Release(DMAHandle);
+        goto error_exit;
+    }
+
+    Adapter_AddrToWordPair(PhysAddr.Address_p, 0,
+                           &FlowDescriptor_p->DMA_Addr.Addr,
+                           &FlowDescriptor_p->DMA_Addr.UpperAddr);
+
+    *FlowHandle_p = (PCL_FlowHandle_t)Element_p;
+
+    PCL_Rc = PCL_STATUS_OK;
+
+error_exit:
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Add
+ */
+PCL_Status_t
+PCL_Flow_Add(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowParams_t * const FlowParams,
+        const PCL_FlowHandle_t FlowHandle)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    DMAResource_Handle_t DMAHandle;
+    DMAResource_AddrPair_t PhysAddr;
+    EIP207_Flow_Error_t res;
+    EIP207_Flow_FR_InputData_t FlowData;
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    List_Element_t * Element_p = (List_Element_t*)FlowHandle;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t PCL_Flow_Add \n");
+
+    // validate interface id
+    if (InterfaceId >= ADAPTER_PCL_MAX_FLUE_DEVICES)
+        return PCL_INVALID_PARAMETER;
+
+    // check valid flow handle
+    if (Element_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
+
+    // check valid flow record descriptor
+    if (FlowDescriptor_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    Dev_p = &Dev_Instance[InterfaceId];
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("PCL_Flow_Add: no device lock, not initialized?\n");
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // check interface is initialised
+    if (!Dev_p->PCL_IsInitialized)
+    {
+        LOG_CRIT("PCL_Flow_Add: Not initialized\n");
+        goto error_exit;
+    }
+
+    // Fill in the input data
+    DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(FlowParams->transform);
+    if (DMAHandle)
+    {
+        if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS, &PhysAddr) < 0)
+        {
+            LOG_CRIT("PCL_Flow_Add: Failed to obtain physical address.\n");
+            goto error_exit;
+        }
+    }
+    else
+    {
+        PhysAddr.Domain    = DMARES_DOMAIN_BUS;
+        PhysAddr.Address_p = AdapterPCL_Int_To_Ptr(
+                                    EIP207_Flow_Record_Dummy_Addr_Get());
+    }
+
+    FlowData.Flags               = FlowParams->flags;
+    FlowData.HashID.Word32[0]    = FlowParams->FlowID[0];
+    FlowData.HashID.Word32[1]    = FlowParams->FlowID[1];
+    FlowData.HashID.Word32[2]    = FlowParams->FlowID[2];
+    FlowData.HashID.Word32[3]    = FlowParams->FlowID[3];
+    FlowData.SW_FR_Reference     = FlowParams->FlowIndex;
+    Adapter_AddrToWordPair(PhysAddr.Address_p,0,
+                           &FlowData.Xform_DMA_Addr.Addr,
+                           &FlowData.Xform_DMA_Addr.UpperAddr);
+
+    FlowData.fLarge = false;
+
+#ifndef ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+    /* Determine whether we have a large transform record. */
+    if (DMAHandle)
+    {
+        DMAResource_Record_t * Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+        if (Rec_p->fIsLargeTransform)
+           FlowData.fLarge = true;
+    }
+#endif // !ADAPTER_PCL_USE_LARGE_TRANSFORM_DISABLE
+
+    LOG_INFO("\n\t\t EIP207_Flow_FR_Add \n");
+
+    // Add the record
+    res = EIP207_Flow_FR_Add(Dev_p->EIP207_IOArea_p,
+                             FlowHashTableId,
+                             FlowDescriptor_p,
+                             &FlowData);
+    if (res == EIP207_FLOW_OUT_OF_MEMORY_ERROR)
+    {
+        LOG_CRIT("PCL_FLow_Add: failed to install flow, out of memory\n");
+    }
+    else if (res == EIP207_FLOW_NO_ERROR)
+    {
+       PCL_Rc = PCL_STATUS_OK;
+    }
+    else
+    {
+        LOG_CRIT("PCL_FLow_Add: failed to install flow, internal error\n");
+    }
+
+error_exit:
+
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Release
+ */
+PCL_Status_t
+PCL_Flow_Release(
+        const unsigned int InterfaceId,
+        const unsigned int FlowHashTableId,
+        const PCL_FlowHandle_t FlowHandle)
+{
+    PCL_Status_t PCL_Rc = PCL_ERROR;
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    List_Element_t * Element_p = (List_Element_t*)FlowHandle;
+    AdapterPCL_Device_Instance_Data_t * Dev_p;
+
+    LOG_INFO("\n\t PCL_Flow_Release \n");
+
+    IDENTIFIER_NOT_USED(InterfaceId);
+    IDENTIFIER_NOT_USED(FlowHashTableId);
+    IDENTIFIER_NOT_USED(FlowHandle);
+
+    // check valid flow handle
+    if (Element_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
+
+    // check valid flow record descriptor
+    if (FlowDescriptor_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    Dev_p = &Dev_Instance[InterfaceId];
+
+    if (Adapter_Lock_CS_Get(&Dev_p->AdapterPCL_DevCS) == Adapter_Lock_NULL)
+    {
+        LOG_CRIT("PCL_Flow_Release: no device lock, not initialized?\n");
+        return PCL_ERROR;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&Dev_p->AdapterPCL_DevCS))
+        return PCL_STATUS_BUSY;
+
+    // check interface is initialised
+    if (!Dev_p->PCL_IsInitialized)
+    {
+        LOG_CRIT("PCL_Flow_Release: Not initialized\n");
+        goto error_exit;
+    }
+
+    DMAResource_Release(FlowDescriptor_p->DMA_Handle);
+
+    // Put the record descriptor back on the free list
+    {
+        List_Status_t List_Rc;
+
+        List_Rc = List_AddToHead(Dev_p->FreeListID,
+                                 NULL,
+                                 Element_p);
+        if (List_Rc != LIST_STATUS_OK)
+        {
+            LOG_CRIT("PCL_Flow_Release: "
+                     "failed to put descriptor on the free list\n");
+            goto error_exit;
+        }
+    }
+
+    PCL_Rc = PCL_STATUS_OK;
+
+error_exit:
+    Adapter_Lock_CS_Leave(&Dev_p->AdapterPCL_DevCS);
+
+    return PCL_Rc;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * PCL_Flow_Get_ReadOnly
+ */
+PCL_Status_t
+PCL_Flow_Get_ReadOnly(
+        const PCL_FlowHandle_t FlowHandle,
+        PCL_FlowParams_t * const FlowParams_p)
+{
+    EIP207_Flow_FR_Dscr_t * FlowDescriptor_p;
+    EIP207_Flow_FR_OutputData_t FlowData;
+    EIP207_Flow_Error_t res;
+    List_Element_t * Element_p = (List_Element_t*)FlowHandle;
+
+    LOG_INFO("\n\t PCL_Flow_Get_ReadOnly \n");
+
+    // check valid flow handle
+    if (Element_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    FlowDescriptor_p = (EIP207_Flow_FR_Dscr_t *)Element_p->DataObject_p;
+
+    // check valid flow record descriptor
+    if (FlowDescriptor_p == NULL)
+        return PCL_INVALID_PARAMETER;
+
+    LOG_INFO("\n\t\t EIP207_Flow_FR_Read \n");
+
+    res = EIP207_Flow_FR_Read(Dev_Instance[0].EIP207_IOArea_p,
+                             0,
+                             FlowDescriptor_p,
+                             &FlowData);
+    if (res == EIP207_FLOW_ARGUMENT_ERROR)
+    {
+        return PCL_INVALID_PARAMETER;
+    }
+    else if (res != EIP207_FLOW_NO_ERROR)
+    {
+        return PCL_ERROR;
+    }
+
+    FlowParams_p->LastTimeLo = FlowData.LastTimeLo;
+    FlowParams_p->LastTimeHi = FlowData.LastTimeHi;
+
+    FlowParams_p->PacketsCounterLo = FlowData.PacketsCounter;
+    FlowParams_p->PacketsCounterHi = 0;
+
+    FlowParams_p->OctetsCounterLo = FlowData.OctetsCounterLo;
+    FlowParams_p->OctetsCounterHi = FlowData.OctetsCounterHi;
+
+    return PCL_STATUS_OK;
+}
+
+/* end of file adapter_pcl_generic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_dma.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_dma.c
new file mode 100644
index 0000000..4bf0a49
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_dma.c
@@ -0,0 +1,1989 @@
+/* adapter_pec_dma.c
+ *
+ * Packet Engine Control (PEC) API Implementation
+ * using DMA mode.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_pec.h"            // PEC_* (the API we implement here)
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter PEC configuration
+#include "c_adapter_pec.h"
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Adapter PEC device API
+#include "adapter_pecdev_dma.h" // Adapter_PECDev_*
+
+// Adapter Locking internal API
+#include "adapter_lock.h"       // Adapter_Lock_*
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+#include "api_pec_sg.h"         // PEC_SG_* (the API we implement here)
+#endif
+
+// Runtime Power Management Device Macros API
+#include "rpm_device_macros.h"  // RPM_*
+
+// Logging API
+#include "log.h"
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_mgmt.h"        // DMAResource management functions
+#include "dmares_rw.h"          // DMAResource buffer access.
+#include "dmares_addr.h"        // DMAResource addr translation functions.
+#include "dmares_buf.h"         // DMAResource buffer allocations
+
+// Standard IOToken API
+#include "iotoken.h"
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcpy, memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t
+
+
+#ifndef ADAPTER_PE_MODE_DHM
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+    void * User_p;
+    DMABuf_Handle_t SrcPkt_Handle;
+    DMABuf_Handle_t DstPkt_Handle;
+    DMABuf_Handle_t Token_Handle;
+    unsigned int Bypass_WordCount;
+} Adapter_SideChannelRecord_t;
+
+
+/* Side channel FIFO
+   - Normal operation: PEC_Packet_Put adds a record containing several
+                                      words for each packet.
+                       PEC_Packet_Get pops one record for each packet, fills
+                                      fields into result descriptor.
+   - Contiuous scatter mode: PEC_Scatter_Preload adds a record
+                                      with DestPkt_Handle only for each scatter
+                                      buffer.
+                             PEC_Packet_Get pops a record for each scatter
+                                      buffer used. Can do PostDMA for each
+                                      scatter buffer, will not fill in fields
+                                      in result descriptor.
+*/
+typedef struct
+{
+    int Size;
+    int ReadIndex;
+    int WriteIndex;
+    Adapter_SideChannelRecord_t Records[1 + ADAPTER_PEC_MAX_PACKETS +
+                                        ADAPTER_PEC_MAX_LOGICDESCR];
+} AdapterPEC_SideChannelFIFO_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static volatile bool PEC_IsInitialized[ADAPTER_PEC_DEVICE_COUNT];
+static volatile bool PEC_ContinuousScatter[ADAPTER_PEC_DEVICE_COUNT];
+
+// Lock and critical section for PEC_Init/Uninit()
+static ADAPTER_LOCK_DEFINE(AdapterPEC_InitLock);
+static Adapter_Lock_CS_t AdapterPEC_InitCS;
+
+// Locks and critical sections for PEC_Packet_Put()
+static Adapter_Lock_t AdapterPEC_PutLock[ADAPTER_PEC_DEVICE_COUNT];
+static Adapter_Lock_CS_t AdapterPEC_PutCS[ADAPTER_PEC_DEVICE_COUNT];
+
+// Locks and critical sections for PEC_Packet_Get()
+static Adapter_Lock_t AdapterPEC_GetLock[ADAPTER_PEC_DEVICE_COUNT];
+static Adapter_Lock_CS_t AdapterPEC_GetCS[ADAPTER_PEC_DEVICE_COUNT];
+
+static AdapterPEC_SideChannelFIFO_t
+Adapter_SideChannelFIFO[ADAPTER_PEC_DEVICE_COUNT];
+
+static struct
+{
+    volatile PEC_NotifyFunction_t ResultNotifyCB_p;
+    volatile unsigned int ResultsCount;
+
+    volatile PEC_NotifyFunction_t CommandNotifyCB_p;
+    volatile unsigned int CommandsCount;
+
+} PEC_Notify[ADAPTER_PEC_DEVICE_COUNT];
+
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+/*----------------------------------------------------------------------------
+ * AdapterPEC_InterruptHandlerResultNotify
+ *
+ * This function is the interrupt handler for the PEC interrupt
+ * sources that indicate the arrival of a a result descriptor..There
+ * may be several interrupt sources.
+ *
+ * This function is used to invoke the PEC result notification callback.
+ */
+static void
+AdapterPEC_InterruptHandlerResultNotify(
+        const int nIRQ,
+        const unsigned int flags)
+{
+    unsigned int InterfaceId = Adapter_PECDev_IRQToInferfaceId(nIRQ);
+
+    IDENTIFIER_NOT_USED(flags);
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+    {
+        LOG_CRIT("AdapterPEC_InterruptHandlerResultNotify"
+                 "InterfaceId out of range\n");
+        return;
+    }
+
+    Adapter_PECDev_Disable_ResultIRQ(InterfaceId);
+
+    LOG_INFO("AdapterPEC_InterruptHandlerResultNotify: Enter\n");
+
+    if (PEC_Notify[InterfaceId].ResultNotifyCB_p != NULL)
+    {
+        PEC_NotifyFunction_t CBFunc_p;
+
+        // Keep the callback on stack to allow registration
+        // of another result notify request from callback
+        CBFunc_p = PEC_Notify[InterfaceId].ResultNotifyCB_p;
+
+        PEC_Notify[InterfaceId].ResultNotifyCB_p = NULL;
+        PEC_Notify[InterfaceId].ResultsCount = 0;
+
+        LOG_INFO(
+            "AdapterPEC_InterruptHandlerResultNotify: "
+            "Invoking PEC result notify callback for interface %d\n",
+            InterfaceId);
+
+        CBFunc_p();
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterPEC_InterruptHandlerCommandNotify
+ *
+ * This function is the interrupt handler for the PEC interrupt sources.that
+ * indicate that there is again freee space for new command descriptors.
+ *
+ * This function is used to invoke the PEC command notification callback.
+ */
+static void
+AdapterPEC_InterruptHandlerCommandNotify(
+        const int nIRQ,
+        const unsigned int flags)
+{
+    unsigned int InterfaceId = Adapter_PECDev_IRQToInferfaceId(nIRQ);
+
+    IDENTIFIER_NOT_USED(flags);
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+    {
+        LOG_CRIT("AdapterPEC_InterruptHandlerCommandNotify"
+                 "InterfaceId out of range\n");
+        return;
+    }
+
+    Adapter_PECDev_Disable_CommandIRQ(InterfaceId);
+
+    LOG_INFO("AdapterPEC_InterruptHandlerCommandNotify: Enter\n");
+
+    if (PEC_Notify[InterfaceId].CommandNotifyCB_p != NULL)
+    {
+        PEC_NotifyFunction_t CBFunc_p;
+
+        // Keep the callback on stack to allow registration
+        // of another command notify request from callback
+        CBFunc_p = PEC_Notify[InterfaceId].CommandNotifyCB_p;
+
+        PEC_Notify[InterfaceId].CommandNotifyCB_p = NULL;
+        PEC_Notify[InterfaceId].CommandsCount = 0;
+
+        LOG_INFO(
+            "AdapterPEC_InterruptHandlerCommandNotify: "
+            "Invoking PEC command notify callback interface=%d\n",
+            InterfaceId);
+
+        CBFunc_p();
+    }
+}
+#endif /* ADAPTER_PEC_INTERRUPTS_ENABLE */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_MakeCommandNotify_CallBack
+ */
+static inline void
+Adapter_MakeCommandNotify_CallBack(unsigned int InterfaceId)
+{
+    unsigned int PacketSlotsEmptyCount;
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return;
+
+    if (PEC_Notify[InterfaceId].CommandNotifyCB_p != NULL)
+    {
+        PacketSlotsEmptyCount = Adapter_PECDev_GetFreeSpace(InterfaceId);
+
+        if (PEC_Notify[InterfaceId].CommandsCount <= PacketSlotsEmptyCount)
+        {
+            PEC_NotifyFunction_t CBFunc_p;
+
+            // Keep the callback on stack to allow registeration
+            // of another result notify request from callback
+            CBFunc_p = PEC_Notify[InterfaceId].CommandNotifyCB_p;
+
+            PEC_Notify[InterfaceId].CommandNotifyCB_p = NULL;
+            PEC_Notify[InterfaceId].CommandsCount = 0;
+
+            LOG_INFO(
+                "PEC_Packet_Get: "
+                "Invoking command notify callback\n");
+
+            CBFunc_p();
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECResgisterSA_BounceIfRequired
+ *
+ * Returns false in case of error.
+ * Allocate a bounce buffer and copy the data in case this if required.
+ */
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+static bool
+Adapter_PECRegisterSA_BounceIfRequired(
+        DMAResource_Handle_t *DMAHandle_p)
+{
+    DMAResource_Handle_t DMAHandle = *DMAHandle_p;
+    DMAResource_Record_t * Rec_p;
+    DMAResource_AddrPair_t BounceHostAddr;
+    void * HostAddr;
+    int dmares;
+
+    // skip null handles
+    if (!DMAResource_IsValidHandle(DMAHandle))
+        return true;    // no error
+
+    Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+
+    // skip proper buffers
+    if (!Adapter_DMAResource_IsForeignAllocated(DMAHandle))
+    {
+        Rec_p->bounce.Bounce_Handle = NULL;
+        return true;    // no error
+    }
+
+    {
+        DMAResource_Properties_t BounceProperties;
+
+        // used as uint32_t array
+        BounceProperties.Alignment  = Adapter_DMAResource_Alignment_Get();
+        BounceProperties.Bank       = ADAPTER_PEC_BANK_SA;
+        BounceProperties.fCached    = false;
+        BounceProperties.Size       = Rec_p->Props.Size;
+
+        HostAddr = Adapter_DMAResource_HostAddr(DMAHandle);
+
+        dmares = DMAResource_Alloc(
+                     BounceProperties,
+                     &BounceHostAddr,
+                     &Rec_p->bounce.Bounce_Handle);
+
+        // bounce buffer handle is stored in the DMA Resource Record
+        // of the original buffer, which links the two
+        // this will be used when freeing the buffer
+        // but also when the SA is referenced in packet put
+
+        if (dmares != 0)
+        {
+            LOG_CRIT(
+                "PEC_SA_Register: "
+                "Failed to alloc bounce buffer (error %d)\n",
+                dmares);
+            return false;   // error!
+        }
+        LOG_INFO(
+            "PEC_SA_Register: "
+            "Bouncing SA: %p to %p\n",
+            DMAHandle,
+            Rec_p->bounce.Bounce_Handle);
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+        DMAResource_SwapEndianness_Set(Rec_p->bounce.Bounce_Handle, true);
+#endif
+
+    }
+
+    // copy the data to the bounce buffer
+    memcpy(
+        BounceHostAddr.Address_p,
+        HostAddr,
+        Rec_p->Props.Size);
+
+    *DMAHandle_p = Rec_p->bounce.Bounce_Handle;
+    return true;        // no error
+}
+#endif /* ADAPTER_PEC_REMOVE_BOUNCEBUFFERS */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_FIFO_Put
+ *
+ * Put packet information into the side channel FIFO
+ */
+static bool
+Adapter_FIFO_Put(AdapterPEC_SideChannelFIFO_t *FIFO,
+                 void *User_p,
+                 DMABuf_Handle_t SrcPkt_Handle,
+                 DMABuf_Handle_t DstPkt_Handle,
+                 DMABuf_Handle_t Token_Handle,
+                 unsigned int Bypass_WordCount)
+{
+    int WriteIndex = FIFO->WriteIndex;
+    int ReadIndex = FIFO->ReadIndex;
+    if (WriteIndex == ReadIndex - 1 ||
+        (ReadIndex == 0 && WriteIndex == FIFO->Size - 1))
+    {
+        LOG_CRIT("Side channel FIFO full\n");
+        return false;
+    }
+    FIFO->Records[WriteIndex].User_p = User_p;
+    FIFO->Records[WriteIndex].SrcPkt_Handle = SrcPkt_Handle;
+    FIFO->Records[WriteIndex].DstPkt_Handle = DstPkt_Handle;
+
+    FIFO->Records[WriteIndex].Token_Handle = Token_Handle;
+    if (!DMABuf_Handle_IsSame(&Token_Handle, &DMABuf_NULLHandle))
+    {
+        FIFO->Records[WriteIndex].Bypass_WordCount = Bypass_WordCount;
+    }
+
+    WriteIndex += 1;
+    if (WriteIndex == FIFO->Size)
+        WriteIndex = 0;
+    FIFO->WriteIndex = WriteIndex;
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_FIFO_Get
+ *
+ * Get and remove the oldest entry from the side channel FIFO.
+ */
+static bool
+Adapter_FIFO_Get(AdapterPEC_SideChannelFIFO_t *FIFO,
+                 void **User_p,
+                 DMABuf_Handle_t *SrcPkt_Handle_p,
+                 DMABuf_Handle_t *DstPkt_Handle_p,
+                 DMABuf_Handle_t *Token_Handle_p,
+                 unsigned int *Bypass_WordCount_p)
+{
+    int WriteIndex = FIFO->WriteIndex;
+    int ReadIndex = FIFO->ReadIndex;
+    if (WriteIndex == ReadIndex)
+    {
+        LOG_CRIT("Trying to read from empty FIFO\n");
+        return false;
+    }
+    if (User_p)
+        *User_p = FIFO->Records[ReadIndex].User_p;
+    if (SrcPkt_Handle_p)
+        *SrcPkt_Handle_p = FIFO->Records[ReadIndex].SrcPkt_Handle;
+    *DstPkt_Handle_p = FIFO->Records[ReadIndex].DstPkt_Handle;
+
+    if (Token_Handle_p)
+        *Token_Handle_p = FIFO->Records[ReadIndex].Token_Handle;
+    if (Token_Handle_p != NULL &&
+        !DMABuf_Handle_IsSame(Token_Handle_p, &DMABuf_NULLHandle) &&
+        Bypass_WordCount_p != NULL)
+        *Bypass_WordCount_p = FIFO->Records[ReadIndex].Bypass_WordCount;
+
+    ReadIndex += 1;
+    if (ReadIndex == FIFO->Size)
+        ReadIndex = 0;
+    FIFO->ReadIndex = ReadIndex;
+    return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_FIFO_Withdraw
+ *
+ * Withdraw the most recently added record from the side channel FIFO.
+ */
+static void
+Adapter_FIFO_Withdraw(
+        AdapterPEC_SideChannelFIFO_t *FIFO)
+{
+    int WriteIndex = FIFO->WriteIndex;
+    if (WriteIndex == FIFO->ReadIndex)
+    {
+        LOG_CRIT("Adapter_FIFO_Withdraw: FIFO is empty\n");
+    }
+    if (WriteIndex == 0)
+        WriteIndex = FIFO->Size - 1;
+    else
+        WriteIndex -= 1;
+    FIFO->WriteIndex = WriteIndex;
+}
+
+
+/* Adapter_Packet_Prepare
+ *
+ * In case of bounce buffers, allocate bounce buffers for the packet and
+ * the packet token.
+ * Copy source packet and token into the bounce buffers.
+ * Perform PreDMA on all packet buffers (source, destination and token).
+ */
+static PEC_Status_t
+Adapter_Packet_Prepare(
+        const unsigned int InterfaceId,
+        const PEC_CommandDescriptor_t *Cmd_p)
+{
+    DMAResource_Handle_t SrcPkt_Handle, DstPkt_Handle, Token_Handle;
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    unsigned int ParticleCount;
+    unsigned int i;
+    DMABuf_Handle_t ParticleHandle;
+    DMAResource_Handle_t DMARes_Handle;
+    uint8_t * DummyPtr;
+    unsigned int ParticleSize;
+#endif
+
+    SrcPkt_Handle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(Cmd_p->SrcPkt_Handle);
+    DstPkt_Handle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(Cmd_p->DstPkt_Handle);
+    Token_Handle = Adapter_DMABuf_Handle2DMAResourceHandle(Cmd_p->Token_Handle);
+
+    if (!DMAResource_IsValidHandle(SrcPkt_Handle) &&
+        !DMAResource_IsValidHandle(DstPkt_Handle))
+        return PEC_STATUS_OK; // For record invalidation in the Record Cache
+    else if (!DMAResource_IsValidHandle(SrcPkt_Handle) ||
+             (!DMAResource_IsValidHandle(DstPkt_Handle) &&
+              !PEC_ContinuousScatter[InterfaceId]))
+    {
+        LOG_CRIT("PEC_Packet_Put: invalid source or destination handle\n");
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+
+    // Token handle
+    if (DMAResource_IsValidHandle(Token_Handle))
+    {
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+        DMAResource_Record_t * Rec_p =
+            DMAResource_Handle2RecordPtr(Token_Handle);
+        if (Adapter_DMAResource_IsForeignAllocated(Token_Handle))
+        {
+            // Bounce buffer required.
+            DMAResource_AddrPair_t BounceHostAddr;
+            void * HostAddr;
+            int dmares;
+            DMAResource_Properties_t BounceProperties;
+
+            // used as uint32_t array
+            BounceProperties.Alignment  = Adapter_DMAResource_Alignment_Get();
+            BounceProperties.Bank       = ADAPTER_PEC_BANK_TOKEN;
+            BounceProperties.fCached    = false;
+            BounceProperties.Size       = Rec_p->Props.Size;
+
+            HostAddr = Adapter_DMAResource_HostAddr(Token_Handle);
+
+            dmares = DMAResource_Alloc(
+                BounceProperties,
+                &BounceHostAddr,
+                &Rec_p->bounce.Bounce_Handle);
+
+            // bounce buffer handle is stored in the DMA Resource Record
+            // of the original buffer, which links the two
+            // this will be used when freeing the buffer
+            // but also when obtaining the bus address.
+
+            if (dmares != 0)
+            {
+                LOG_CRIT(
+                    "PEC_Packet_Put: "
+                    "Failed to alloc bounce buffer (error %d)\n",
+                dmares);
+                return PEC_ERROR_INTERNAL;   // error!
+            }
+
+            LOG_INFO(
+                "PEC_Packet_Putr: "
+                "Bouncing Token: %p to %p\n",
+                Token_Handle,
+                Rec_p->bounce.Bounce_Handle);
+
+            // copy the data to the bounce buffer
+            memcpy(
+                BounceHostAddr.Address_p,
+                HostAddr,
+                Rec_p->Props.Size);
+
+            Token_Handle = Rec_p->bounce.Bounce_Handle;
+        }
+        else
+        {
+            Rec_p->bounce.Bounce_Handle = NULL;
+        }
+#endif // !ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+        // Convert token data to packet engine endianness format
+        DMAResource_SwapEndianness_Set(Token_Handle, true);
+
+        DMAResource_Write32Array(
+            Token_Handle,
+            0,
+            Cmd_p->Token_WordCount,
+            Adapter_DMAResource_HostAddr(Token_Handle));
+#endif // ADAPTER_PEC_ARMRING_ENABLE_SWAP
+
+        DMAResource_PreDMA(Token_Handle, 0, 0);
+    }
+
+    // Source packet handle
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_GetCapacity(Cmd_p->SrcPkt_Handle, &ParticleCount);
+
+    if (ParticleCount > 0)
+    {
+        for (i=0; i<ParticleCount; i++)
+        {
+            PEC_SGList_Read(Cmd_p->SrcPkt_Handle,
+                            i,
+                            &ParticleHandle,
+                            &ParticleSize,
+                            &DummyPtr);
+            DMARes_Handle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
+            DMAResource_PreDMA(DMARes_Handle, 0, 0);
+        }
+    }
+    else
+#endif
+    { // Not a gather packet,
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+        DMAResource_Record_t * Rec_p =
+            DMAResource_Handle2RecordPtr(SrcPkt_Handle);
+        DMAResource_Record_t * Dst_Rec_p =
+            DMAResource_Handle2RecordPtr(DstPkt_Handle);
+        if (Adapter_DMAResource_IsForeignAllocated(SrcPkt_Handle) ||
+            Adapter_DMAResource_IsForeignAllocated(DstPkt_Handle))
+        {
+            // Bounce buffer required. Use a single bounce buffer for
+            // both the source and the destination packet.
+            DMAResource_AddrPair_t BounceHostAddr;
+            void * HostAddr;
+            int dmares;
+            DMAResource_Properties_t BounceProperties;
+
+            // used as uint32_t array
+            BounceProperties.Alignment  = Adapter_DMAResource_Alignment_Get();
+            BounceProperties.Bank       = ADAPTER_PEC_BANK_PACKET;
+            BounceProperties.fCached    = false;
+            BounceProperties.Size       = MAX(Rec_p->Props.Size,
+                                              Dst_Rec_p->Props.Size);
+
+            HostAddr = Adapter_DMAResource_HostAddr(SrcPkt_Handle);
+
+            dmares = DMAResource_Alloc(
+                BounceProperties,
+                &BounceHostAddr,
+                &Rec_p->bounce.Bounce_Handle);
+
+            // bounce buffer handle is stored in the DMA Resource Record
+            // of the original buffer, which links the two
+            // this will be used when freeing the buffer
+            // but also when obtaining the bus address.
+
+            if (dmares != 0)
+            {
+                LOG_CRIT(
+                    "PEC_Packet_Put: "
+                    "Failed to alloc bounce buffer (error %d)\n",
+                dmares);
+                return PEC_ERROR_INTERNAL;   // error!
+            }
+            LOG_INFO(
+                "PEC_Packet_Putr: "
+                "Bouncing Packet: %p to %p\n",
+                SrcPkt_Handle,
+                Rec_p->bounce.Bounce_Handle);
+
+
+            // copy the data to the bounce buffer
+            memcpy(
+                BounceHostAddr.Address_p,
+                HostAddr,
+                Rec_p->Props.Size);
+
+            DstPkt_Handle = SrcPkt_Handle = Rec_p->bounce.Bounce_Handle;
+
+            Dst_Rec_p->bounce.Bounce_Handle = Rec_p->bounce.Bounce_Handle;
+        }
+        else
+        {
+            Rec_p->bounce.Bounce_Handle = NULL;
+            Dst_Rec_p->bounce.Bounce_Handle = NULL;
+        }
+#endif
+        DMAResource_PreDMA(SrcPkt_Handle, 0, 0);
+    }
+    // Destination packet handle, not for continuous scatter.
+    if (PEC_ContinuousScatter[InterfaceId])
+        return PEC_STATUS_OK;
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_GetCapacity(Cmd_p->DstPkt_Handle, &ParticleCount);
+
+    if (ParticleCount > 0)
+    {
+        for (i=0; i<ParticleCount; i++)
+        {
+            PEC_SGList_Read(Cmd_p->DstPkt_Handle,
+                            i,
+                            &ParticleHandle,
+                            &ParticleSize,
+                            &DummyPtr);
+            DMARes_Handle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
+            DMAResource_PreDMA(DMARes_Handle, 0, 0);
+        }
+    }
+    else
+#endif
+    if (SrcPkt_Handle != DstPkt_Handle)
+    {
+        // Only if source and destination are distinct.
+        // When bounce buffers were used, these are not distinct.
+        DMAResource_PreDMA(DstPkt_Handle, 0, 0);
+    }
+    return PEC_STATUS_OK;
+}
+
+
+/* Adapter_Packet_Finalize
+ *
+ * Perform PostDMA on all DMA buffers (source, destination and token).
+ * Copy the destination packet from the bounce buffer into the final location.
+ * Deallocate any bounce buffers (packet and token).
+ */
+static PEC_Status_t
+Adapter_Packet_Finalize(
+        DMABuf_Handle_t DMABuf_SrcPkt_Handle,
+        DMABuf_Handle_t DMABuf_DstPkt_Handle,
+        DMABuf_Handle_t DMABuf_Token_Handle)
+{
+    DMAResource_Handle_t SrcPkt_Handle, DstPkt_Handle, Token_Handle;
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    unsigned int ParticleCount;
+    unsigned int i;
+    DMABuf_Handle_t ParticleHandle;
+    DMAResource_Handle_t DMARes_Handle;
+    uint8_t * DummyPtr;
+    unsigned int ParticleSize;
+#endif
+
+    SrcPkt_Handle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(DMABuf_SrcPkt_Handle);
+    DstPkt_Handle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(DMABuf_DstPkt_Handle);
+
+    if (!DMAResource_IsValidHandle(SrcPkt_Handle) &&
+        !DMAResource_IsValidHandle(DstPkt_Handle))
+        return PEC_STATUS_OK; // For record invalidation in the Record Cache
+
+    Token_Handle = Adapter_DMABuf_Handle2DMAResourceHandle(DMABuf_Token_Handle);
+
+    // Token Handle.
+    if (DMAResource_IsValidHandle(Token_Handle))
+    {
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+        DMAResource_Record_t * Rec_p =
+            DMAResource_Handle2RecordPtr(Token_Handle);
+        if (Rec_p->bounce.Bounce_Handle != NULL)
+        {
+            // Post DMA and release the bounce buffer.
+            DMAResource_PostDMA(Rec_p->bounce.Bounce_Handle, 0, 0);
+            DMAResource_Release(Rec_p->bounce.Bounce_Handle);
+        }
+        else
+#endif
+        {
+            DMAResource_PostDMA(Token_Handle, 0, 0);
+        }
+    }
+    // Destination packet handle
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_GetCapacity(DMABuf_DstPkt_Handle, &ParticleCount);
+
+    if (ParticleCount > 0)
+    {
+        for (i=0; i<ParticleCount; i++)
+        {
+            PEC_SGList_Read(DMABuf_DstPkt_Handle,
+                            i,
+                            &ParticleHandle,
+                            &ParticleSize,
+                            &DummyPtr);
+            DMARes_Handle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
+            DMAResource_PostDMA(DMARes_Handle, 0, 0);
+        }
+    }
+    else
+#endif
+    {
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+        DMAResource_Record_t * Rec_p =
+            DMAResource_Handle2RecordPtr(DstPkt_Handle);
+        void * HostAddr = Adapter_DMAResource_HostAddr(DstPkt_Handle);
+        if (Rec_p->bounce.Bounce_Handle != NULL)
+        {
+            void * BounceHostAddr =
+                Adapter_DMAResource_HostAddr(Rec_p->bounce.Bounce_Handle);
+            // Post DMA, copy and release the bounce buffer.
+            DMAResource_PostDMA(Rec_p->bounce.Bounce_Handle, 0, 0);
+
+            memcpy( HostAddr, BounceHostAddr, Rec_p->Props.Size);
+
+            DMAResource_Release(Rec_p->bounce.Bounce_Handle);
+            SrcPkt_Handle = DstPkt_Handle;
+        }
+        else
+#endif
+        {
+            DMAResource_PostDMA(DstPkt_Handle, 0, 0);
+        }
+
+    }
+    // Source packet handle
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_GetCapacity(DMABuf_SrcPkt_Handle, &ParticleCount);
+
+    if (ParticleCount > 0)
+    {
+        for (i=0; i<ParticleCount; i++)
+        {
+            PEC_SGList_Read(DMABuf_SrcPkt_Handle,
+                            i,
+                            &ParticleHandle,
+                            &ParticleSize,
+                            &DummyPtr);
+            DMARes_Handle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
+            DMAResource_PostDMA(DMARes_Handle, 0, 0);
+        }
+    }
+    else
+#endif
+    if (SrcPkt_Handle != DstPkt_Handle)
+    {
+        // Only if source and destination are distinct.
+        // When bounce buffers were used, these are not distinct.
+        DMAResource_PostDMA(SrcPkt_Handle, 0, 0);
+    }
+
+    return PEC_STATUS_OK;
+}
+
+
+#ifdef ADAPTER_PEC_RPM_EIP202_DEVICE0_ID
+/*----------------------------------------------------------------------------
+ * AdapterPEC_Resume
+ */
+static int
+AdapterPEC_Resume(void * p)
+{
+    int InterfaceId = *(int *)p;
+
+    if (InterfaceId < 0 || InterfaceId < ADAPTER_PEC_RPM_EIP202_DEVICE0_ID)
+        return -3; // error
+
+    InterfaceId -= ADAPTER_PEC_RPM_EIP202_DEVICE0_ID;
+
+    return Adapter_PECDev_Resume(InterfaceId);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterPEC_Suspend
+ */
+static int
+AdapterPEC_Suspend(void * p)
+{
+    int InterfaceId = *(int *)p;
+
+    if (InterfaceId < 0 || InterfaceId < ADAPTER_PEC_RPM_EIP202_DEVICE0_ID)
+        return -3; // error
+
+    InterfaceId -= ADAPTER_PEC_RPM_EIP202_DEVICE0_ID;
+
+    return Adapter_PECDev_Suspend(InterfaceId);
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Capabilities_Get
+ */
+PEC_Status_t
+PEC_Capabilities_Get(
+        PEC_Capabilities_t * const Capabilities_p)
+{
+    return Adapter_PECDev_Capabilities_Get(Capabilities_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Init
+ */
+PEC_Status_t
+PEC_Init(
+        const unsigned int InterfaceId,
+        const PEC_InitBlock_t * const InitBlock_p)
+{
+    LOG_INFO("\n\t PEC_Init \n");
+
+    if (!InitBlock_p)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    Adapter_Lock_CS_Set(&AdapterPEC_InitCS, &AdapterPEC_InitLock);
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_InitCS))
+        return PEC_STATUS_BUSY;
+
+    // ensure we init only once
+    if (PEC_IsInitialized[InterfaceId])
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_STATUS_OK;
+    }
+    PEC_ContinuousScatter[InterfaceId] = InitBlock_p->fContinuousScatter;
+
+    // Allocate the Put lock
+    AdapterPEC_PutLock[InterfaceId] = Adapter_Lock_Alloc();
+    if (AdapterPEC_PutLock[InterfaceId] == NULL)
+    {
+        LOG_CRIT("PEC_Init: PutLock allocation failed\n");
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_ERROR_INTERNAL;
+    }
+    Adapter_Lock_CS_Set(&AdapterPEC_PutCS[InterfaceId],
+                         AdapterPEC_PutLock[InterfaceId]);
+
+    // Allocate the Get lock
+    AdapterPEC_GetLock[InterfaceId] = Adapter_Lock_Alloc();
+    if (AdapterPEC_GetLock[InterfaceId] == NULL)
+    {
+        LOG_CRIT("PEC_Init: GetLock allocation failed\n");
+        Adapter_Lock_Free(AdapterPEC_PutLock[InterfaceId]);
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_ERROR_INTERNAL;
+    }
+    Adapter_Lock_CS_Set(&AdapterPEC_GetCS[InterfaceId],
+                         AdapterPEC_GetLock[InterfaceId]);
+
+    ZEROINIT(PEC_Notify[InterfaceId]);
+
+    if (RPM_DEVICE_INIT_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                    AdapterPEC_Suspend,
+                                    AdapterPEC_Resume) != RPM_SUCCESS)
+        return PEC_ERROR_INTERNAL;
+
+    // Init the device
+    if (Adapter_PECDev_Init(InterfaceId, InitBlock_p) != PEC_STATUS_OK)
+    {
+        (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId);
+        LOG_CRIT("PEC_Init: Adapter_PECDev_Init failed\n");
+        Adapter_Lock_Free(AdapterPEC_PutLock[InterfaceId]);
+        Adapter_Lock_Free(AdapterPEC_GetLock[InterfaceId]);
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_ERROR_INTERNAL;
+    }
+
+    (void)RPM_DEVICE_INIT_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId);
+
+    Adapter_SideChannelFIFO[InterfaceId].Size =
+        sizeof(Adapter_SideChannelFIFO[InterfaceId].Records) /
+        sizeof(Adapter_SideChannelFIFO[InterfaceId].Records[0]);
+    Adapter_SideChannelFIFO[InterfaceId].WriteIndex = 0;
+    Adapter_SideChannelFIFO[InterfaceId].ReadIndex = 0;
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    // enable the descriptor done interrupt
+    LOG_INFO("PEC_Init: Registering interrupt handler\n");
+
+    Adapter_PECDev_SetResultHandler(
+            InterfaceId,
+            AdapterPEC_InterruptHandlerResultNotify);
+
+    Adapter_PECDev_SetCommandHandler(
+            InterfaceId,
+            AdapterPEC_InterruptHandlerCommandNotify);
+#endif /* ADAPTER_PEC_INTERRUPTS_ENABLE */
+
+    PEC_IsInitialized[InterfaceId] = true;
+
+    LOG_INFO("\n\t PEC_Init done \n");
+
+    Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_UnInit
+ */
+PEC_Status_t
+PEC_UnInit(
+        const unsigned int InterfaceId)
+{
+    LOG_INFO("\n\t PEC_UnInit \n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    Adapter_Lock_CS_Set(&AdapterPEC_InitCS, &AdapterPEC_InitLock);
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_InitCS))
+        return PEC_STATUS_BUSY;
+
+    // ensure we uninit only once
+    if (!PEC_IsInitialized[InterfaceId])
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_STATUS_OK;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_PutCS[InterfaceId]))
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_STATUS_BUSY;
+    }
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_GetCS[InterfaceId]))
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_STATUS_BUSY;
+    }
+
+    if (RPM_DEVICE_UNINIT_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                true) != RPM_SUCCESS)
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+        Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+        return PEC_ERROR_INTERNAL;
+    }
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    Adapter_PECDev_Disable_ResultIRQ(InterfaceId);
+    Adapter_PECDev_Disable_CommandIRQ(InterfaceId);
+#endif
+
+    Adapter_PECDev_UnInit(InterfaceId);
+
+    PEC_IsInitialized[InterfaceId] = false;
+
+    (void)RPM_DEVICE_UNINIT_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId);
+
+    Adapter_Lock_CS_Leave(&AdapterPEC_GetCS[InterfaceId]);
+    Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+
+    // Free Get lock
+    Adapter_Lock_Free(Adapter_Lock_CS_Get(&AdapterPEC_GetCS[InterfaceId]));
+    Adapter_Lock_CS_Set(&AdapterPEC_GetCS[InterfaceId], Adapter_Lock_NULL);
+
+    // Free Put lock
+    Adapter_Lock_Free(Adapter_Lock_CS_Get(&AdapterPEC_PutCS[InterfaceId]));
+    Adapter_Lock_CS_Set(&AdapterPEC_PutCS[InterfaceId], Adapter_Lock_NULL);
+
+    LOG_INFO("\n\t PEC_UnInit done \n");
+
+    Adapter_Lock_CS_Leave(&AdapterPEC_InitCS);
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SA_Register
+ */
+PEC_Status_t
+PEC_SA_Register(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t SA_Handle1,
+        DMABuf_Handle_t SA_Handle2,
+        DMABuf_Handle_t SA_Handle3)
+{
+    DMAResource_Handle_t DMAHandle1, DMAHandle2, DMAHandle3;
+    PEC_Status_t res;
+
+    LOG_INFO("\n\t PEC_SA_Register \n");
+
+    IDENTIFIER_NOT_USED(InterfaceId);
+
+    DMAHandle1 = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle1);
+    DMAHandle2 = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle2);
+    DMAHandle3 = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle3);
+
+    // The SA, State Record and ARC4 State Record are arrays of uint32_t.
+    // The caller provides them in host-native format.
+    // This function converts them to device-native format
+    // using DMAResource and in-place operations.
+
+    // Endianness conversion for the 1st SA memory block (Main SA Record)
+#ifdef ADAPTER_PEC_ARMRING_ENABLE_SWAP
+    {
+        DMAResource_Record_t * const Rec_p =
+            DMAResource_Handle2RecordPtr(DMAHandle1);
+
+        if (Rec_p == NULL)
+            return PEC_ERROR_INTERNAL;
+
+        DMAResource_SwapEndianness_Set(DMAHandle1, true);
+
+        DMAResource_Write32Array(
+            DMAHandle1,
+            0,
+            Rec_p->Props.Size / 4,
+            Adapter_DMAResource_HostAddr(DMAHandle1));
+    }
+
+    // Endianness conversion for the 2nd SA memory block (State Record)
+    if (DMAHandle2 != NULL)
+    {
+        DMAResource_Record_t * const Rec_p =
+            DMAResource_Handle2RecordPtr(DMAHandle2);
+
+        if (Rec_p == NULL)
+            return PEC_ERROR_INTERNAL;
+
+        // The 2nd SA memory block can never be a subset of
+        // the 1st SA memory block so it is safe to perform
+        // the endianness conversion
+        DMAResource_SwapEndianness_Set(DMAHandle2, true);
+
+        DMAResource_Write32Array(
+            DMAHandle2,
+            0,
+            Rec_p->Props.Size / 4,
+            Adapter_DMAResource_HostAddr(DMAHandle2));
+    }
+
+    // Endianness conversion for the 3d SA memory block (ARC4 State Record)
+    if (DMAHandle3 != NULL)
+    {
+        DMAResource_Record_t * const Rec_p =
+            DMAResource_Handle2RecordPtr(DMAHandle3);
+
+        if (Rec_p == NULL)
+            return PEC_ERROR_INTERNAL;
+
+        // The 3d SA memory block can never be a subset of
+        // the 2nd SA memory block.
+
+        // Check if the 3d SA memory block is not a subset of the 1st one
+        if (!Adapter_DMAResource_IsSubRangeOf(DMAHandle3, DMAHandle1))
+        {
+            // The 3d SA memory block is a separate buffer and does not
+            // overlap with the 1st SA memory block,
+            // so the endianness conversion must be done
+            DMAResource_SwapEndianness_Set(DMAHandle3, true);
+
+            DMAResource_Write32Array(
+                    DMAHandle3,
+                    0,
+                    Rec_p->Props.Size / 4,
+                    Adapter_DMAResource_HostAddr(DMAHandle3));
+        }
+    }
+#endif // ADAPTER_PEC_ARMRING_ENABLE_SWAP
+
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+    // Bounce the SA buffers if required
+    // Check if the 3d SA memory block is not a subset of the 1st one
+    if (DMAHandle3 != NULL &&
+        !Adapter_DMAResource_IsSubRangeOf(DMAHandle3, DMAHandle1))
+    {
+        if (!Adapter_PECRegisterSA_BounceIfRequired(&DMAHandle3))
+            return PEC_ERROR_INTERNAL;
+    }
+
+    if (!Adapter_PECRegisterSA_BounceIfRequired(&DMAHandle1))
+        return PEC_ERROR_INTERNAL;
+
+    if (!Adapter_PECRegisterSA_BounceIfRequired(&DMAHandle2))
+        return PEC_ERROR_INTERNAL;
+#endif
+
+    res = Adapter_PECDev_SA_Prepare(SA_Handle1, SA_Handle2, SA_Handle3);
+    if (res != PEC_STATUS_OK)
+    {
+        LOG_WARN(
+            "PEC_SA_Register: "
+            "Adapter_PECDev_PrepareSA returned %d\n",
+            res);
+        return PEC_ERROR_INTERNAL;
+    }
+
+    // now use DMAResource to ensure the engine
+    // can read the memory blocks using DMA
+    DMAResource_PreDMA(DMAHandle1, 0, 0);     // 0,0 = "entire buffer"
+
+    if (DMAHandle2 != NULL)
+        DMAResource_PreDMA(DMAHandle2, 0, 0);
+
+    // Check if the 3d SA memory block is not a subset of the 1st one
+    if (DMAHandle3 != NULL &&
+        !Adapter_DMAResource_IsSubRangeOf(DMAHandle3, DMAHandle1))
+        DMAResource_PreDMA(DMAHandle3, 0, 0);
+
+    LOG_INFO("\n\t PEC_SA_Register done \n");
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SA_UnRegister
+ */
+PEC_Status_t
+PEC_SA_UnRegister(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t SA_Handle1,
+        DMABuf_Handle_t SA_Handle2,
+        DMABuf_Handle_t SA_Handle3)
+{
+    DMAResource_Handle_t SA_Handle[3];
+    PEC_Status_t res;
+    int i, MaxHandles;
+
+    LOG_INFO("\n\t PEC_SA_UnRegister \n");
+
+    IDENTIFIER_NOT_USED(InterfaceId);
+
+    res = Adapter_PECDev_SA_Remove(SA_Handle1, SA_Handle2, SA_Handle3);
+    if (res != PEC_STATUS_OK)
+    {
+        LOG_CRIT(
+            "PEC_SA_UnRegister: "
+            "Adapter_PECDev_SA_Remove returned %d\n",
+            res);
+        return PEC_ERROR_INTERNAL;
+    }
+
+    SA_Handle[0] = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle1);
+    SA_Handle[1] = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle2);
+    SA_Handle[2] = Adapter_DMABuf_Handle2DMAResourceHandle(SA_Handle3);
+
+    // Check if the 3d SA memory block is not a subset of the 1st one
+    if (SA_Handle[0] != NULL &&
+        SA_Handle[2] != NULL &&
+        Adapter_DMAResource_IsSubRangeOf(SA_Handle[2], SA_Handle[0]))
+        MaxHandles = 2;
+    else
+        MaxHandles = 3;
+
+    for (i = 0; i < MaxHandles; i++)
+    {
+        if (DMAResource_IsValidHandle(SA_Handle[i]))
+        {
+            DMAResource_Handle_t DMAHandle = SA_Handle[i];
+            void *HostAddr;
+            DMAResource_Record_t * Rec_p =
+                DMAResource_Handle2RecordPtr(DMAHandle);
+
+            // Check if a bounce buffer is in use
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+            void * OrigHostAddr;
+            DMAResource_Record_t * HostRec_p = Rec_p;
+
+            OrigHostAddr = Adapter_DMAResource_HostAddr(DMAHandle);
+
+            if (Adapter_DMAResource_IsForeignAllocated(SA_Handle[i]))
+            {
+                // Get bounce buffer handle and its record
+                DMAHandle = HostRec_p->bounce.Bounce_Handle;
+                Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+            }
+#endif /* ADAPTER_PEC_REMOVE_BOUNCEBUFFERS */
+
+            HostAddr = Adapter_DMAResource_HostAddr(DMAHandle);
+            // ensure we look at valid engine-written data
+            // 0,0 = "entire buffer"
+            DMAResource_PostDMA(DMAHandle, 0, 0);
+
+            // convert to host format
+            if (Rec_p != NULL)
+                DMAResource_Read32Array(
+                    DMAHandle,
+                    0,
+                    Rec_p->Props.Size / 4,
+                    HostAddr);
+
+            // copy from bounce buffer to original buffer
+#ifndef ADAPTER_PEC_REMOVE_BOUNCEBUFFERS
+            if (Adapter_DMAResource_IsForeignAllocated(SA_Handle[i]) &&
+                HostRec_p != NULL)
+            {
+                // copy the data from bounce to original buffer
+                memcpy(
+                    OrigHostAddr,
+                    HostAddr,
+                    HostRec_p->Props.Size);
+
+                // free the bounce handle
+                DMAResource_Release(HostRec_p->bounce.Bounce_Handle);
+                HostRec_p->bounce.Bounce_Handle = NULL;
+            }
+#endif /* ADAPTER_PEC_REMOVE_BOUNCEBUFFERS */
+        } // if handle valid
+    } // for
+
+    LOG_INFO("\n\t PEC_SA_UnRegister done\n");
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Packet_Put
+ */
+PEC_Status_t
+PEC_Packet_Put(
+        const unsigned int InterfaceId,
+        const PEC_CommandDescriptor_t * Commands_p,
+        const unsigned int CommandsCount,
+        unsigned int * const PutCount_p)
+{
+    unsigned int CmdLp;
+    unsigned int PktCnt;
+    unsigned int CmdDescriptorCount;
+    PEC_Status_t res = 0, res2, PEC_Rc = PEC_STATUS_OK;
+    unsigned int FreeSlots;
+
+    LOG_INFO("\n\t PEC_Packet_Put \n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+#ifdef ADAPTER_PEC_STRICT_ARGS
+    if (Commands_p == NULL ||
+        CommandsCount == 0 ||
+        PutCount_p == NULL)
+    {
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+#endif
+
+    // initialize the output parameters
+    *PutCount_p = 0;
+
+#ifdef ADAPTER_PEC_STRICT_ARGS
+    // validate the descriptors
+    // (error out before bounce buffer allocation)
+    for (CmdLp = 0; CmdLp < CommandsCount; CmdLp++)
+        if (Commands_p[CmdLp].Bypass_WordCount > 255)
+            return PEC_ERROR_BAD_PARAMETER;
+#endif /* ADAPTER_PEC_STRICT_ARGS */
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_PutCS[InterfaceId]))
+        return PEC_STATUS_BUSY;
+
+    if (!PEC_IsInitialized[InterfaceId])
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+        return PEC_ERROR_BAD_USE_ORDER;
+    }
+
+    CmdDescriptorCount = MIN(ADAPTER_PEC_MAX_LOGICDESCR, CommandsCount);
+    FreeSlots = 0;
+    CmdLp = 0;
+    while (CmdLp < CmdDescriptorCount)
+    {
+        unsigned int j;
+        unsigned int count;
+        unsigned int NonSGPackets;
+
+#ifndef ADAPTER_PEC_ENABLE_SCATTERGATHER
+        NonSGPackets = CmdDescriptorCount - CmdLp;
+        // All remaining packets are non-SG.
+#else
+        unsigned int GatherParticles;
+        unsigned int ScatterParticles;
+        unsigned int i;
+
+        for (i = CmdLp; i < CmdDescriptorCount; i++)
+        {
+            PEC_SGList_GetCapacity(Commands_p[i].SrcPkt_Handle,
+                                   &GatherParticles);
+            if (PEC_ContinuousScatter[InterfaceId])
+                ScatterParticles = 0;
+            else
+                PEC_SGList_GetCapacity(Commands_p[i].DstPkt_Handle,
+                                       &ScatterParticles);
+            if ( GatherParticles > 0 || ScatterParticles > 0)
+                break;
+        }
+        NonSGPackets = i - CmdLp;
+
+        if (NonSGPackets == 0)
+        {
+            bool fSuccess;
+
+            if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                                   InterfaceId,
+                                          RPM_FLAG_SYNC) != RPM_SUCCESS)
+            {
+                PEC_Rc = PEC_ERROR_INTERNAL;
+                break;
+            }
+
+            // First packet found is scatter gather.
+            fSuccess = Adapter_PECDev_TestSG(InterfaceId,
+                                             GatherParticles,
+                                             ScatterParticles);
+
+            (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                           InterfaceId,
+                                           RPM_FLAG_ASYNC);
+
+            if (!fSuccess)
+            {
+                PEC_Rc = PEC_ERROR_INTERNAL;
+                break;
+            }
+
+            // Process a single SG packet in this iteration.
+            FreeSlots = 1;
+        }
+        else
+#endif
+        if (FreeSlots == 0)
+        {
+            if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                                   InterfaceId,
+                                          RPM_FLAG_SYNC) != RPM_SUCCESS)
+            {
+                PEC_Rc = PEC_ERROR_INTERNAL;
+                break;
+            }
+
+            // Allow all non-SG packets to be processed in this iteration,
+            // but limited by the number of free slots in the ring(s).
+            FreeSlots = Adapter_PECDev_GetFreeSpace(InterfaceId);
+
+            (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                           InterfaceId,
+                                           RPM_FLAG_ASYNC);
+
+            if (FreeSlots > NonSGPackets)
+                FreeSlots = NonSGPackets;
+
+            if (FreeSlots == 0)
+                break;
+        }
+
+        for (PktCnt=0; PktCnt<FreeSlots; PktCnt++)
+        {
+            res = Adapter_Packet_Prepare(InterfaceId,
+                                         Commands_p + CmdLp + PktCnt);
+            if (res != PEC_STATUS_OK)
+            {
+                LOG_CRIT("%s: Adapter_Packet_Prepare error %d\n", __func__, res);
+                PEC_Rc = res;
+                break;
+            }
+
+            if (!PEC_ContinuousScatter[InterfaceId])
+            {
+                Adapter_FIFO_Put(&(Adapter_SideChannelFIFO[InterfaceId]),
+                                 Commands_p[CmdLp+PktCnt].User_p,
+                                 Commands_p[CmdLp+PktCnt].SrcPkt_Handle,
+                                 Commands_p[CmdLp+PktCnt].DstPkt_Handle,
+                                 Commands_p[CmdLp+PktCnt].Token_Handle,
+                                 Commands_p[CmdLp+PktCnt].Bypass_WordCount);
+            }
+        }
+
+        // RPM_Device_IO_Start() must be called for each successfully submitted
+        // packet
+        for (j = 0; j < PktCnt; j++)
+        {
+            // Skipped error checking to reduce code complexity
+            (void)RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                                InterfaceId,
+                                            RPM_FLAG_SYNC);
+        }
+
+        res2 = Adapter_PECDev_Packet_Put(InterfaceId,
+                                         Commands_p + CmdLp,
+                                         PktCnt,
+                                         &count);
+        if (res2 != PEC_STATUS_OK)
+        {
+            LOG_CRIT("%s: Adapter_PECDev_Packet_Put error %d\n", __func__, res2);
+            PEC_Rc = res2;
+        }
+
+        FreeSlots -= count;
+        *PutCount_p += count;
+
+        if (count <  PktCnt)
+        {
+            LOG_WARN("PEC_Packet_Put: withdrawing %d prepared packets\n",
+                     PktCnt - count);
+
+            for (j = count; j < PktCnt; j++)
+            {
+                if (!PEC_ContinuousScatter[InterfaceId])
+                {
+                    Adapter_FIFO_Withdraw(&(Adapter_SideChannelFIFO[InterfaceId]));
+                    Adapter_Packet_Finalize(Commands_p[CmdLp + j].SrcPkt_Handle,
+                                            Commands_p[CmdLp + j].DstPkt_Handle,
+                                            Commands_p[CmdLp + j].Token_Handle);
+                }
+
+                // RPM_DEVICE_IO_STOP_MACRO() must be called here for packets
+                // which could not be successfully submitted,
+                // for example because device queue was full
+                (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                               InterfaceId,
+                                               RPM_FLAG_ASYNC);
+            }
+            break;
+        }
+
+        CmdLp += count;
+
+        if (res != PEC_STATUS_OK || res2 != PEC_STATUS_OK)
+        {
+            PEC_Rc = PEC_ERROR_INTERNAL;
+            break;
+        }
+    } // while
+
+    LOG_INFO("\n\t PEC_Packet_Put done \n");
+
+    Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+
+    return PEC_Rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Packet_Get
+ */
+PEC_Status_t
+PEC_Packet_Get(
+        const unsigned int InterfaceId,
+        PEC_ResultDescriptor_t * Results_p,
+        const unsigned int ResultsLimit,
+        unsigned int * const GetCount_p)
+{
+    LOG_INFO("\n\t PEC_Packet_Get \n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+#ifdef ADAPTER_PEC_STRICT_ARGS
+    if (Results_p == NULL ||
+        GetCount_p == NULL ||
+        ResultsLimit == 0)
+    {
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+#endif
+
+    // initialize the output parameter
+    *GetCount_p = 0;
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_GetCS[InterfaceId]))
+        return PEC_STATUS_BUSY;
+
+    if (!PEC_IsInitialized[InterfaceId])
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_GetCS[InterfaceId]);
+        return PEC_ERROR_BAD_USE_ORDER;
+    }
+
+    // read descriptors from PEC device
+    {
+        PEC_Status_t res;
+        unsigned int ResLp;
+        unsigned int Limit = MIN(ResultsLimit, ADAPTER_PEC_MAX_LOGICDESCR);
+        unsigned int count;
+        DMABuf_Handle_t Token_Handle = DMABuf_NULLHandle;
+
+        res=Adapter_PECDev_Packet_Get(InterfaceId,
+                                      Results_p,
+                                      Limit,
+                                      &count);
+        if (res != PEC_STATUS_OK)
+        {
+            LOG_CRIT("PEC_Packet_Get() returned error: %d\n", res);
+            Adapter_Lock_CS_Leave(&AdapterPEC_GetCS[InterfaceId]);
+            return res;
+        }
+
+        for (ResLp = 0; ResLp < count; ResLp++)
+        {
+            // To help CommandNotifyCB
+            if (ResLp == count-1)
+                Adapter_MakeCommandNotify_CallBack(InterfaceId);
+
+            (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID +
+                                                        InterfaceId,
+                                           RPM_FLAG_ASYNC);
+            if (PEC_ContinuousScatter[InterfaceId])
+            {
+                unsigned int i;
+                DMABuf_Handle_t DestHandle = DMABuf_NULLHandle;
+                DMAResource_Handle_t DMARes_Handle;
+                if (Results_p[ResLp].NumParticles == 1)
+                {
+                    /* No real scatter, can fixup using single destination
+                       handle */
+                    Adapter_FIFO_Get(&Adapter_SideChannelFIFO[InterfaceId],
+                                     NULL,
+                                     NULL,
+                                     &DestHandle,
+                                     NULL,
+                                     NULL);
+                    DMARes_Handle =
+                        Adapter_DMABuf_Handle2DMAResourceHandle(DestHandle);
+                    DMAResource_PostDMA(DMARes_Handle, 0, 0);
+#ifdef ADAPTER_AUTO_FIXUP
+                    IOToken_Fixup(Results_p[ResLp].OutputToken_p,
+                                  DestHandle);
+#endif
+                    Results_p[ResLp].User_p = NULL;
+                    Results_p[ResLp].SrcPkt_Handle = DMABuf_NULLHandle;
+                    Results_p[ResLp].DstPkt_Handle = DestHandle;
+                    Results_p[ResLp].Bypass_WordCount = 0;
+                    if (!DMABuf_Handle_IsSame(&Results_p[ResLp].DstPkt_Handle,
+                                              &DMABuf_NULLHandle))
+                    {
+                        Results_p[ResLp].DstPkt_p =
+                            Adapter_DMAResource_HostAddr(
+                                Adapter_DMABuf_Handle2DMAResourceHandle(
+                                    Results_p[ResLp].DstPkt_Handle));
+                    }
+                    else
+                    {
+                        Results_p[ResLp].DstPkt_p = NULL;
+                    }
+                }
+                else
+                {
+#if defined(ADAPTER_PEC_ENABLE_SCATTERGATHER) && defined(ADAPTER_AUTO_FIXUP)
+                    DMAResource_Record_t * Rec_p;
+                    PEC_Status_t PEC_Rc;
+                    DMABuf_Handle_t Fixup_SGList; /* scatter list for Fixup in continuous scatter mode */
+                    PEC_Rc = PEC_SGList_Create(Results_p[ResLp].NumParticles,
+                                               &Fixup_SGList);
+#endif
+                    for (i = 0; i < Results_p[ResLp].NumParticles; i++)
+                    {
+                        Adapter_FIFO_Get(&Adapter_SideChannelFIFO[InterfaceId],
+                                         NULL,
+                                         NULL,
+                                         &DestHandle,
+                                         NULL,
+                                     NULL);
+                        DMARes_Handle =
+                            Adapter_DMABuf_Handle2DMAResourceHandle(DestHandle);
+                        DMAResource_PostDMA(DMARes_Handle, 0, 0);
+#if defined(ADAPTER_PEC_ENABLE_SCATTERGATHER) && defined(ADAPTER_AUTO_FIXUP)
+                        if (PEC_Rc == PEC_STATUS_OK)
+                        {
+                            Rec_p = DMAResource_Handle2RecordPtr(DMARes_Handle);
+
+                            PEC_SGList_Write(Fixup_SGList,
+                                             i,
+                                             DestHandle,
+                                             Rec_p->Props.Size);
+                        }
+#endif
+                    }
+#if defined(ADAPTER_PEC_ENABLE_SCATTERGATHER) && defined(ADAPTER_AUTO_FIXUP)
+                    if (PEC_Rc == PEC_STATUS_OK)
+                    {
+                        IOToken_Fixup(Results_p[ResLp].OutputToken_p,
+                              Fixup_SGList);
+                        PEC_SGList_Destroy(Fixup_SGList);
+                    }
+
+#endif
+                    Results_p[ResLp].User_p = NULL;
+                    Results_p[ResLp].SrcPkt_Handle = DMABuf_NULLHandle;
+                    Results_p[ResLp].DstPkt_Handle = DMABuf_NULLHandle;
+                    Results_p[ResLp].Bypass_WordCount = 0;
+                }
+            }
+            else
+            {
+                Adapter_FIFO_Get(&(Adapter_SideChannelFIFO[InterfaceId]),
+                                 &(Results_p[ResLp].User_p),
+                                 &(Results_p[ResLp].SrcPkt_Handle),
+                                 &(Results_p[ResLp].DstPkt_Handle),
+                                 &Token_Handle,
+                                 &(Results_p[ResLp].Bypass_WordCount));
+
+                Adapter_Packet_Finalize(Results_p[ResLp].SrcPkt_Handle,
+                                    Results_p[ResLp].DstPkt_Handle,
+                                    Token_Handle);
+#ifdef ADAPTER_AUTO_FIXUP
+                IOToken_Fixup(Results_p[ResLp].OutputToken_p,
+                              Results_p[ResLp].DstPkt_Handle);
+#endif
+
+                if (!DMABuf_Handle_IsSame(&Results_p[ResLp].DstPkt_Handle,
+                                          &DMABuf_NULLHandle))
+                {
+                    Results_p[ResLp].DstPkt_p =
+                        Adapter_DMAResource_HostAddr(
+                            Adapter_DMABuf_Handle2DMAResourceHandle(
+                                Results_p[ResLp].DstPkt_Handle));
+                }
+                else
+                {
+                    Results_p[ResLp].DstPkt_p = NULL;
+                }
+            }
+            *GetCount_p += 1;
+        } // for
+    }
+
+    LOG_INFO("\n\t PEC_Packet_Get done \n");
+
+    Adapter_Lock_CS_Leave(&AdapterPEC_GetCS[InterfaceId]);
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_CD_Control_Write
+ *
+ * Write the Control1 and Control2 engine-specific fields in the
+ * Command Descriptor The other fields (such as SrcPkt_ByteCount and
+ * Bypass_WordCount must have been filled in already.
+ *
+ * Command_p (input, output)
+ *     Command descriptor whose Control1 and Control2 fields must be filled in.
+ *
+ * PacketParams_p (input)
+ *     Per-packet parameters.
+ *
+ * This function is not implemented for all engine types.
+ */
+PEC_Status_t
+PEC_CD_Control_Write(
+    PEC_CommandDescriptor_t *Command_p,
+    const PEC_PacketParams_t *PacketParams_p)
+{
+    return Adapter_PECDev_CD_Control_Write(Command_p, PacketParams_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_RD_Status_Read
+ */
+PEC_Status_t
+PEC_RD_Status_Read(
+        const PEC_ResultDescriptor_t * const Result_p,
+        PEC_ResultStatus_t * const ResultStatus_p)
+{
+    return Adapter_PECDev_RD_Status_Read(Result_p, ResultStatus_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_CommandNotify_Request
+ */
+PEC_Status_t
+PEC_CommandNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int CommandsCount)
+{
+    unsigned int PacketSlotsEmptyCount;
+
+    LOG_INFO("\n\t PEC_CommandNotify_Request \n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    if (CBFunc_p == NULL ||
+        CommandsCount == 0 ||
+        CommandsCount > ADAPTER_PEC_MAX_PACKETS)
+    {
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+
+    if (!PEC_IsInitialized[InterfaceId])
+        return PEC_ERROR_BAD_USE_ORDER;
+
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return PEC_ERROR_INTERNAL;
+
+    PacketSlotsEmptyCount = Adapter_PECDev_GetFreeSpace(InterfaceId);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                   RPM_FLAG_ASYNC);
+
+    if (CommandsCount <= PacketSlotsEmptyCount)
+    {
+        LOG_INFO(
+            "PEC_CommandNotify_Request: "
+            "Invoking command notify callback immediately\n");
+
+        CBFunc_p();
+    }
+    else
+    {
+        PEC_Notify[InterfaceId].CommandsCount = CommandsCount;
+        PEC_Notify[InterfaceId].CommandNotifyCB_p = CBFunc_p;
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+        if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                      RPM_FLAG_SYNC) != RPM_SUCCESS)
+            return PEC_ERROR_INTERNAL;
+
+        /* Note that space for new commands may have become available before
+         * the call to PEC_CommandNotify_Request and the associated interrupt
+         * may already be pending. In this case the interrupt will occur
+         * immediately.
+         */
+        Adapter_PECDev_Enable_CommandIRQ(InterfaceId);
+
+        (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                       RPM_FLAG_ASYNC);
+#endif /* ADAPTER_PEC_INTERRUPTS_ENABLE */
+    }
+
+    LOG_INFO("\n\t PEC_CommandNotify_Request done \n");
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_ResultNotify_Request
+ */
+PEC_Status_t
+PEC_ResultNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int ResultsCount)
+{
+    LOG_INFO("\n\t PEC_ResultNotify_Request \n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    if (CBFunc_p == NULL ||
+        ResultsCount == 0 ||
+        ResultsCount > ADAPTER_PEC_MAX_PACKETS)
+    {
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+
+    if (!PEC_IsInitialized[InterfaceId])
+        return PEC_ERROR_BAD_USE_ORDER;
+
+    // install it
+    PEC_Notify[InterfaceId].ResultsCount = ResultsCount;
+    PEC_Notify[InterfaceId].ResultNotifyCB_p = CBFunc_p;
+
+#ifdef ADAPTER_PEC_INTERRUPTS_ENABLE
+    if (RPM_DEVICE_IO_START_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                  RPM_FLAG_SYNC) != RPM_SUCCESS)
+        return PEC_ERROR_INTERNAL;
+
+    /* Note that results may have become available before the call
+       to PEC_ResultNotify_Request and the associated interrupts may already
+       be pending. In this case the interrupt will occur immediately.
+     */
+    Adapter_PECDev_Enable_ResultIRQ(InterfaceId);
+
+    (void)RPM_DEVICE_IO_STOP_MACRO(ADAPTER_PEC_RPM_EIP202_DEVICE0_ID + InterfaceId,
+                                   RPM_FLAG_ASYNC);
+#endif /* ADAPTER_PEC_INTERRUPTS_ENABLE */
+
+    LOG_INFO("\n\t PEC_ResultNotify_Request done\n");
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Scatter_Preload
+ */
+PEC_Status_t
+PEC_Scatter_Preload(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t * Handles_p,
+        const unsigned int HandlesCount,
+        unsigned int * const AcceptedCount_p)
+{
+    PEC_Status_t rc;
+    unsigned int i;
+    unsigned int HandlesToUse,ri,wi;
+        LOG_INFO("\n\t PEC_Scatter_Preload\n");
+
+    if (InterfaceId >= ADAPTER_PEC_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    if (!Adapter_Lock_CS_Enter(&AdapterPEC_PutCS[InterfaceId]))
+        return PEC_STATUS_BUSY;
+
+    if (!PEC_IsInitialized[InterfaceId] || !PEC_ContinuousScatter[InterfaceId])
+    {
+        Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+        return PEC_ERROR_BAD_USE_ORDER;
+    }
+    ri = Adapter_SideChannelFIFO[InterfaceId].ReadIndex;
+    wi = Adapter_SideChannelFIFO[InterfaceId].WriteIndex;
+    // Compute the number of free slots in the ring from the read/write index
+    // of the side channel FIFO (which is larger than the ring)
+    if (wi >= ri)
+        HandlesToUse = ADAPTER_PEC_MAX_PACKETS - 1 - wi + ri ;
+    else
+        HandlesToUse = ADAPTER_PEC_MAX_PACKETS - 1
+            - Adapter_SideChannelFIFO[InterfaceId].Size - wi + ri;
+    if (HandlesToUse > ADAPTER_PEC_MAX_LOGICDESCR)
+        HandlesToUse = ADAPTER_PEC_MAX_LOGICDESCR;
+    if (HandlesToUse > HandlesCount)
+        HandlesToUse = HandlesCount;
+    for (i=0; i < HandlesToUse; i++)
+    {
+        DMAResource_Handle_t DMARes_Handle =
+            Adapter_DMABuf_Handle2DMAResourceHandle(Handles_p[i]);
+        DMAResource_PreDMA(DMARes_Handle, 0, 0);
+        Adapter_FIFO_Put(&Adapter_SideChannelFIFO[InterfaceId],
+                         NULL,
+                         DMABuf_NULLHandle,
+                         Handles_p[i],
+                         DMABuf_NULLHandle,
+                         0);
+    }
+    rc = Adapter_PECDev_Scatter_Preload(InterfaceId,
+                                        Handles_p,
+                                        HandlesToUse);
+
+    *AcceptedCount_p = HandlesToUse;
+    Adapter_Lock_CS_Leave(&AdapterPEC_PutCS[InterfaceId]);
+    return rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Scatter_PreloadNotify_Request
+ */
+PEC_Status_t
+PEC_Scatter_PreloadNotify_Request(
+        const unsigned int InterfaceId,
+        PEC_NotifyFunction_t CBFunc_p,
+        const unsigned int ConsumedCount)
+{
+    IDENTIFIER_NOT_USED(InterfaceId);
+    IDENTIFIER_NOT_USED(CBFunc_p);
+    IDENTIFIER_NOT_USED(ConsumedCount);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Put_Dump
+ */
+void
+PEC_Put_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpRDRAdmin,
+        const bool fDumpRDRCache)
+{
+    Adapter_PECDev_Put_Dump(InterfaceId,
+                            FirstSlotId,
+                            LastSlotId,
+                            fDumpRDRAdmin,
+                            fDumpRDRCache);
+}
+
+
+
+
+/*----------------------------------------------------------------------------
+ * PEC_Get_Dump
+ */
+void
+PEC_Get_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpRDRAdmin,
+        const bool fDumpRDRCache)
+{
+    Adapter_PECDev_Get_Dump(InterfaceId,
+                            FirstSlotId,
+                            LastSlotId,
+                            fDumpRDRAdmin,
+                            fDumpRDRCache);
+}
+
+
+#endif /* ADAPTER_PE_MODE_DHM */
+
+
+/* end of file adapter_pec_dma.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_pktbuf.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_pktbuf.c
new file mode 100644
index 0000000..d0eec29
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_pec_pktbuf.c
@@ -0,0 +1,206 @@
+/* adapter_pec_pktbuf.c
+ *
+ * Helper functions to access packet data via DMABuf handles, possibly
+ * in scatter-gather lists.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2020-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_pec_pktbuf.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter PEC configuration
+#include "c_adapter_pec.h"
+
+#include "api_pec_sg.h"         // PEC_SG_* (the API we implement here)
+
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Logging API
+#include "log.h"
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_mgmt.h"        // DMAResource management functions
+#include "dmares_rw.h"          // DMAResource buffer access.
+#include "dmares_addr.h"        // DMAResource addr translation functions.
+#include "dmares_buf.h"         // DMAResource buffer allocations
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcpy, memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Adapter_PEC_PktData_Get
+ */
+uint8_t *
+Adapter_PEC_PktData_Get(
+        DMABuf_Handle_t PacketHandle,
+        uint8_t *CopyBuffer_p,
+        unsigned int StartOffs,
+        unsigned int ByteCount)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    unsigned int NofParticles;
+    PEC_SGList_GetCapacity(PacketHandle, &NofParticles);
+    if (NofParticles != 0)
+    {
+        unsigned int TotalByteCount = 0;
+        unsigned int BytesCopied = 0;
+        unsigned int BytesSkip;
+        unsigned int i;
+        unsigned int FragmentByteCount;
+        DMABuf_Handle_t FragmentHandle;
+        uint8_t *FragmentPtr;
+        for (i=0; i<NofParticles; i++)
+        {
+            PEC_SGList_Read(PacketHandle, i, &FragmentHandle,
+                            &FragmentByteCount, &FragmentPtr);
+            if (TotalByteCount + FragmentByteCount >=
+                StartOffs + ByteCount)
+            {
+                // This is the last fragment to visit (possibly the first).
+                if (BytesCopied == 0)
+                {
+                    // No need to copy everything is in single fragment.
+                    return FragmentPtr + StartOffs - TotalByteCount;
+                }
+                else
+                {
+                    // Copy the final fragment.
+                    memcpy(CopyBuffer_p + BytesCopied,
+                           FragmentPtr, ByteCount - BytesCopied);
+                    return CopyBuffer_p;
+                }
+            }
+            else if (TotalByteCount + FragmentByteCount >
+                     StartOffs)
+            {
+                // This fragment contains data that must be copied
+                if (BytesCopied == 0)
+                {
+                    // First fragment containing data to copy, may need to skip
+                    // bytes at start of fragment.
+                    BytesSkip = StartOffs - TotalByteCount;
+                }
+                else
+                {   // Later fragments, copy from start of fragment.
+                    BytesSkip = 0;
+                }
+                if (CopyBuffer_p == NULL)
+                    return NULL; // Skip copying altogether.
+                memcpy(CopyBuffer_p + BytesCopied,
+                       FragmentPtr + BytesSkip,
+                       FragmentByteCount - BytesSkip);
+                BytesCopied += FragmentByteCount - BytesSkip;
+            }
+            TotalByteCount += FragmentByteCount;
+        }
+        // We haven't collected enough data here, return NULL pointer.
+        return NULL;
+    }
+    else
+#endif
+    {
+        DMAResource_Handle_t DMAHandle =
+            Adapter_DMABuf_Handle2DMAResourceHandle(PacketHandle);
+        uint8_t *Packet_p;
+        IDENTIFIER_NOT_USED(CopyBuffer_p);
+        IDENTIFIER_NOT_USED(ByteCount);
+        if (DMAResource_IsValidHandle(DMAHandle))
+        {
+            Packet_p = (uint8_t *)Adapter_DMAResource_HostAddr(DMAHandle) + StartOffs;
+        }
+        else
+        {
+            Packet_p = NULL;
+        }
+        return Packet_p;
+    }
+}
+
+/*----------------------------------------------------------------------------
+ * Adapter_PEC_PktByte_Put
+ */
+void
+Adapter_PEC_PktByte_Put(
+        DMABuf_Handle_t PacketHandle,
+        unsigned int Offset,
+        unsigned int Byte)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    unsigned int NofParticles;
+    PEC_SGList_GetCapacity(PacketHandle, &NofParticles);
+    if (NofParticles != 0)
+    {
+        unsigned int TotalByteCount = 0;
+        unsigned int i;
+        unsigned int FragmentByteCount;
+        DMABuf_Handle_t FragmentHandle;
+        uint8_t *FragmentPtr;
+        for (i=0; i<NofParticles; i++)
+        {
+            PEC_SGList_Read(PacketHandle, i, &FragmentHandle,
+                            &FragmentByteCount, &FragmentPtr);
+            if (TotalByteCount + FragmentByteCount > Offset)
+            {
+                // Found the fragment where the byte must be changed..
+                FragmentPtr[Offset - TotalByteCount] = Byte;
+                return;
+            }
+            TotalByteCount += FragmentByteCount;
+        }
+    }
+    else
+#endif
+    {
+        DMAResource_Handle_t DMAHandle =
+            Adapter_DMABuf_Handle2DMAResourceHandle(PacketHandle);
+        uint8_t *Packet_p;
+        if (DMAResource_IsValidHandle(DMAHandle))
+        {
+            Packet_p = (uint8_t *)Adapter_DMAResource_HostAddr(DMAHandle) + Offset;
+            Packet_p[0] = Byte;
+        }
+    }
+}
+
+
+
+
+/* end of file adapter_pec_dmabuf.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_ring_eip202.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_ring_eip202.c
new file mode 100644
index 0000000..470378a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_ring_eip202.c
@@ -0,0 +1,3012 @@
+/* adapter_ring_eip202.c
+ *
+ * Adapter EIP-202 implementation: EIP-202 specific layer.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// SLAD Adapter PEC Device-specific API
+#include "adapter_pecdev_dma.h"
+
+// Ring Control configuration API
+#include "adapter_ring_eip202.h"
+
+#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
+    defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
+// Record Cache configuration API
+#include "adapter_rc_eip207.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_adapter_eip202.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool
+#include "api_pec.h"
+#include "api_dmabuf.h"
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Convert address to pair of 32-bit words.
+#include "adapter_addrpair.h"
+
+// Adapter interrupts API
+#include "adapter_interrupts.h" // Adapter_Interrupt_*
+
+// Adapter memory allocation API
+#include "adapter_alloc.h"      // Adapter_Alloc/Free
+
+// Driver Framework DMAResource API
+#include "dmares_addr.h"      // AddrTrans_*
+#include "dmares_buf.h"       // DMAResource_Alloc/Release
+#include "dmares_rw.h"        // DMAResource_PreDMA/PostDMA
+#include "dmares_mgmt.h"      // DMAResource_Alloc/Release
+
+#include "device_types.h"  // Device_Handle_t
+#include "device_mgmt.h" // Device_find
+#include "device_rw.h" // Device register read/write
+
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+#include "api_pec_sg.h"         // PEC_SG_* (the API we implement here)
+#endif
+
+// EIP97 Ring Control
+#include "eip202_ring_types.h"
+#include "eip202_cdr.h"
+#include "eip202_rdr.h"
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+#include "shdevxs_prng.h"
+#else
+#include "eip97_global_init.h"
+#endif
+
+#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
+    defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+// EIP-207 Record Cache (RC) interface
+#include "shdevxs_dmapool.h"
+#include "shdevxs_rc.h"
+#else
+// EIP-207 Record Cache (RC) interface
+#include "eip207_rc.h"                  // EIP207_RC_*
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+#endif
+
+#include "clib.h"  // memcpy, ZEROINIT
+
+// Log API
+#include "log.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
+    defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+// The default Record Cache set number to be used
+// Note: Only one cache set is supported by this implementation!
+#define EIP207_RC_SET_NR_DEFAULT              0
+#endif
+#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT || ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+#if defined(ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT) || \
+    defined(ADAPTER_EIP202_RC_DMA_BANK_SUPPORT)
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO   SHDevXS_RC_Record_Dummy_Addr_Get()
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI   0
+#else
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO   EIP207_RC_Record_Dummy_Addr_Get()
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI   0
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+#else
+
+#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO       0xfffffffc
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI       0xffffffff
+#else
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO       3
+#define ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI       0
+#endif
+
+#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT || ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+// Move bit position src in value v to dst.
+#define BIT_MOVE(v, src, dst)  ( ((src) < (dst)) ? \
+    ((v) << ((dst) - (src))) & (1 << (dst)) :  \
+    ((v) >> ((src) - (dst))) & (1 << (dst)))
+
+#ifndef ADAPTER_EIP202_SEPARATE_RINGS
+#define ADAPTER_EIP202_CDR_BYTE_OFFSET              \
+                    (EIP202_RD_CTRL_DATA_MAX_WORD_COUNT * sizeof(uint32_t))
+#endif
+
+
+typedef struct
+{
+    unsigned int CDR_IRQ_ID;
+
+    unsigned int CDR_IRQ_Flags;
+
+    const char * CDR_DeviceName_p;
+
+    unsigned int RDR_IRQ_ID;
+
+    unsigned int RDR_IRQ_Flags;
+
+    const char * RDR_DeviceName_p;
+
+} Adapter_Ring_EIP202_Device_t;
+
+
+#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
+#define ADAPTER_EIP202_TR_ADDRESS       2
+#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
+#define ADAPTER_EIP202_TR_LARGE_ADDRESS 3
+// Bit in first word of SA record to indicate it is large.
+#define ADAPTER_EIP202_TR_ISLARGE              BIT_4
+#endif
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+static const Adapter_Ring_EIP202_Device_t EIP202_Devices [] =
+{
+    ADAPTER_EIP202_DEVICES
+};
+
+// number of devices supported calculated on ADAPTER_EIP202_DEVICES defined
+// in c_adapter_eip202.h
+#define ADAPTER_EIP202_DEVICE_COUNT_ACTUAL \
+        (sizeof(EIP202_Devices) / sizeof(Adapter_Ring_EIP202_Device_t))
+
+static EIP202_CDR_Settings_t  CDR_Settings;
+static EIP202_RDR_Settings_t  RDR_Settings;
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+static unsigned int EIP202_Interrupts[ADAPTER_EIP202_DEVICE_COUNT];
+#endif
+
+static EIP202_Ring_IOArea_t CDR_IOArea[ADAPTER_EIP202_DEVICE_COUNT];
+static EIP202_Ring_IOArea_t RDR_IOArea[ADAPTER_EIP202_DEVICE_COUNT];
+
+static DMAResource_Handle_t CDR_Handle[ADAPTER_EIP202_DEVICE_COUNT];
+static DMAResource_Handle_t RDR_Handle[ADAPTER_EIP202_DEVICE_COUNT];
+
+static  EIP202_ARM_CommandDescriptor_t
+    EIP202_CDR_Entries[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
+
+static  EIP202_ARM_PreparedDescriptor_t
+    EIP202_RDR_Prepared[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
+
+static  EIP202_ARM_ResultDescriptor_t
+    EIP202_RDR_Entries[ADAPTER_EIP202_DEVICE_COUNT][ADAPTER_EIP202_MAX_LOGICDESCR];
+
+static bool EIP202_ContinuousScatter[ADAPTER_EIP202_DEVICE_COUNT];
+
+static const PEC_Capabilities_t CapabilitiesString =
+{
+    "EIP-202 Packet Engine rings=__ (ARM,"        // szTextDescription
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+    "SG,"
+#endif
+#ifndef ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
+    "BB,"
+#endif
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+    "Int)",
+#else
+    "Poll)",
+#endif
+    0
+};
+
+// Static variables used by the adapter_ring_eip202.h interface implementation
+static bool    Adapter_Ring_EIP202_Configured;
+static uint8_t Adapter_Ring_EIP202_HDW;
+static uint8_t Adapter_Ring_EIP202_CFSize;
+static uint8_t Adapter_Ring_EIP202_RFSize;
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+static uint32_t EIP202_SABaseAddr;
+static uint32_t EIP202_SABaseUpperAddr;
+#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+// Static variables used by the adapter_rc_eip207.h interface implementation
+static bool Adapter_RC_EIP207_Configured = true;
+static bool Adapter_RC_EIP207_TRC_Enabled = true;
+static bool Adapter_RC_EIP207_ARC4RC_Enabled;
+static bool Adapter_RC_EIP207_Combined;
+#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+
+// DMA buffer allocation alignment in bytes
+static int Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
+                                        ADAPTER_DMABUF_ALIGNMENT_INVALID;
+
+
+#ifdef ADAPTER_EIP202_ADD_INIT_DIAGNOSTICS
+static void
+Adapter_Register_Dump(void)
+{
+    Device_Handle_t Device=Device_Find("EIP197_GLOBAL");
+    unsigned int i,j,v[256];
+    LOG_CRIT("REGISTER DUMP\n");
+    for (i=0; i<0x100000; i+=1024)
+    {
+        Device_Read32Array(Device, i, v, 256);
+        for (j=0; j<256; j++)
+        {
+            if (v[j])
+            {
+                LOG_CRIT("Addr 0x%08x = 0x%08x\n",i+j*4,v[j]);
+            }
+        }
+    }
+    LOG_CRIT("END REGISTER DUMP\n");
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_RD_OutTokens_Free
+ *
+ * Free Output Tokens in the EIP-202 result descriptors.
+ */
+static void
+AdapterLib_RD_OutTokens_Free(
+        const unsigned int InterfaceId)
+{
+    unsigned int i;
+
+    for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
+        Adapter_Free(EIP202_RDR_Entries[InterfaceId][i].Token_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_RD_OutTokens_Alloc
+ *
+ * Allocate Output Tokens in the EIP-202 result descriptors.
+ */
+static bool
+AdapterLib_RD_OutTokens_Alloc(
+        const unsigned int InterfaceId)
+{
+    unsigned int i;
+
+    for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
+    {
+        uint32_t * p =
+               Adapter_Alloc(IOToken_OutWordCount_Get() * sizeof (uint32_t));
+
+        if (p)
+            EIP202_RDR_Entries[InterfaceId][i].Token_p = p;
+        else
+            goto exit_error;
+    }
+
+    return true;
+
+exit_error:
+    AdapterLib_RD_OutTokens_Free(InterfaceId);
+
+    return false;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_GetPhysAddr
+ *
+ * Obtain the physical address from a DMABuf handle.
+ * Take the bounce handle into account.
+ *
+ */
+static void
+Adapter_GetPhysAddr(
+        const DMABuf_Handle_t Handle,
+        EIP202_DeviceAddress_t *PhysAddr_p)
+{
+    DMAResource_Handle_t DMAHandle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(Handle);
+    DMAResource_Record_t * Rec_p = NULL;
+    DMAResource_AddrPair_t PhysAddr_Pair;
+
+    if (PhysAddr_p == NULL)
+    {
+        LOG_CRIT("Adapter_GetPhysAddr: PANIC\n");
+        return;
+    }
+
+    PhysAddr_p->Addr        = ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO;
+    PhysAddr_p->UpperAddr   = ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI;
+
+    // Note: this function is sometimes invoked with invalid DMA handle
+    //       to obtain a dummy address, not an error.
+    if (!DMAResource_IsValidHandle(DMAHandle))
+        return; // success!
+
+    Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+    if (Rec_p == NULL)
+    {
+        LOG_CRIT("Adapter_GetPhysAddr: failed\n");
+        return;
+    }
+
+#ifndef ADAPTER_EIP202_REMOVE_BOUNCEBUFFERS
+    if (Rec_p->bounce.Bounce_Handle != NULL)
+        DMAHandle = Rec_p->bounce.Bounce_Handle;
+#endif
+
+    if (DMAResource_Translate(DMAHandle, DMARES_DOMAIN_BUS,
+                              &PhysAddr_Pair) == 0)
+    {
+        Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0, &PhysAddr_p->Addr,
+                              &PhysAddr_p->UpperAddr);
+        // success!
+    }
+    else
+    {
+        LOG_CRIT("Adapter_GetPhysAddr: failed\n");
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * BoolToString()
+ *
+ * Convert boolean value to string.
+ */
+static const char *
+BoolToString(
+        bool b)
+{
+    if (b)
+        return "TRUE";
+    else
+        return "false";
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_CDR_Status_Report
+ *
+ * Report the status of the CDR interface
+ *
+ */
+static void
+AdapterLib_Ring_EIP202_CDR_Status_Report(
+        unsigned int InterfaceId)
+{
+    EIP202_Ring_Error_t res;
+    EIP202_CDR_Status_t CDR_Status;
+
+    LOG_CRIT("Status of CDR interface %d\n",InterfaceId);
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_Status_Get \n");
+
+    ZEROINIT(CDR_Status);
+    res = EIP202_CDR_Status_Get(CDR_IOArea + InterfaceId, &CDR_Status);
+    if (res != EIP202_RING_NO_ERROR)
+    {
+        LOG_CRIT("EIP202_CDR_Status_Get returned error\n");
+        return;
+    }
+
+    // Report CDR status
+    LOG_CRIT("CDR Status: CD prep/proc count %d/%d, proc pkt count %d\n",
+             CDR_Status.CDPrepWordCount,
+             CDR_Status.CDProcWordCount,
+             CDR_Status.CDProcPktWordCount);
+
+    if (CDR_Status.fDMAError    ||
+        CDR_Status.fError       ||
+        CDR_Status.fOUFlowError ||
+        CDR_Status.fTresholdInt ||
+        CDR_Status.fTimeoutInt)
+    {
+        // Report CDR errors
+        LOG_CRIT("CDR Status: error(s) detected\n");
+        LOG_CRIT("\tDMA err:       %s\n"
+                 "\tErr:           %s\n"
+                 "\tOvf/under err: %s\n"
+                 "\tThreshold int: %s\n"
+                 "\tTimeout int:   %s\n"
+                 "\tFIFO count:    %d\n",
+                 BoolToString(CDR_Status.fDMAError),
+                 BoolToString(CDR_Status.fError),
+                 BoolToString(CDR_Status.fOUFlowError),
+                 BoolToString(CDR_Status.fTresholdInt),
+                 BoolToString(CDR_Status.fTimeoutInt),
+                 CDR_Status.CDFIFOWordCount);
+    }
+    else
+        LOG_CRIT("CDR Status: all OK, FIFO count: %d\n",
+                 CDR_Status.CDFIFOWordCount);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_RDR_Status_Report
+ *
+ * Report the status of the RDR interface
+ *
+ */
+static void
+AdapterLib_Ring_EIP202_RDR_Status_Report(
+        unsigned int InterfaceId)
+{
+    EIP202_Ring_Error_t res;
+    EIP202_RDR_Status_t RDR_Status;
+
+    LOG_CRIT("Status of RDR interface %d\n",InterfaceId);
+    if (EIP202_ContinuousScatter[InterfaceId])
+        LOG_CRIT("Ring is in continuous scatter mode\n");
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Status_Get \n");
+
+    ZEROINIT(RDR_Status);
+    res = EIP202_RDR_Status_Get(RDR_IOArea + InterfaceId, &RDR_Status);
+    if (res != EIP202_RING_NO_ERROR)
+    {
+        LOG_CRIT("EIP202_RDR_Status_Get returned error\n");
+        return;
+    }
+
+    // Report RDR status
+    LOG_CRIT("RDR Status: RD prep/proc count %d/%d, proc pkt count %d\n",
+             RDR_Status.RDPrepWordCount,
+             RDR_Status.RDProcWordCount,
+             RDR_Status.RDProcPktWordCount);
+
+    if (RDR_Status.fDMAError         ||
+        RDR_Status.fError            ||
+        RDR_Status.fOUFlowError      ||
+        RDR_Status.fRDBufOverflowInt ||
+        RDR_Status.fRDOverflowInt    ||
+        RDR_Status.fTresholdInt      ||
+        RDR_Status.fTimeoutInt)
+    {
+        // Report RDR errors
+        LOG_CRIT("RDR Status: error(s) detected\n");
+        LOG_CRIT("\tDMA err:        %s\n"
+                 "\tErr:            %s\n"
+                 "\tOvf/under err:  %s\n"
+                 "\tBuf ovf:        %s\n"
+                 "\tDescriptor ovf: %s\n"
+                 "\tThreshold int:  %s\n"
+                 "\tTimeout int:    %s\n"
+                 "\tFIFO count:     %d\n",
+                 BoolToString(RDR_Status.fDMAError),
+                 BoolToString(RDR_Status.fError),
+                 BoolToString(RDR_Status.fOUFlowError),
+                 BoolToString(RDR_Status.fRDBufOverflowInt),
+                 BoolToString(RDR_Status.fRDOverflowInt),
+                 BoolToString(RDR_Status.fTresholdInt),
+                 BoolToString(RDR_Status.fTimeoutInt),
+                 RDR_Status.RDFIFOWordCount);
+    }
+    else
+        LOG_CRIT("RDR Status: all OK, FIFO count: %d\n",
+                 RDR_Status.RDFIFOWordCount);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_Status_Report
+ *
+ * Report the status of the CDR and RDR interface
+ *
+ */
+static void
+AdapterLib_Ring_EIP202_Status_Report(
+        unsigned int InterfaceId)
+{
+    AdapterLib_Ring_EIP202_CDR_Status_Report(InterfaceId);
+
+    AdapterLib_Ring_EIP202_RDR_Status_Report(InterfaceId);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_AlignForSize
+ */
+static unsigned int
+AdapterLib_Ring_EIP202_AlignForSize(
+        const unsigned int ByteCount,
+        const unsigned int AlignTo)
+{
+    unsigned int AlignedByteCount = ByteCount;
+
+    // Check if alignment and padding for length alignment is required
+    if (AlignTo > 1 && ByteCount % AlignTo)
+        AlignedByteCount = ByteCount / AlignTo * AlignTo + AlignTo;
+
+    return AlignedByteCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_DMA_Alignment_Determine
+ *
+ * Determine the required EIP-202 DMA alignment value
+ *
+ */
+static bool
+AdapterLib_Ring_EIP202_DMA_Alignment_Determine(void)
+{
+#ifdef ADAPTER_EIP202_ALLOW_UNALIGNED_DMA
+    Adapter_DMAResource_Alignment_Set(1);
+#else
+    // Default alignment value is invalid
+    Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
+                                ADAPTER_DMABUF_ALIGNMENT_INVALID;
+
+    if (Adapter_Ring_EIP202_Configured)
+    {
+        int AlignTo = Adapter_Ring_EIP202_HDW;
+
+        // Determine the EIP-202 master interface hardware data width
+        switch (AlignTo)
+        {
+            case EIP202_RING_DMA_ALIGNMENT_4_BYTES:
+                Adapter_DMAResource_Alignment_Set(4);
+                break;
+            case EIP202_RING_DMA_ALIGNMENT_8_BYTES:
+                Adapter_DMAResource_Alignment_Set(8);
+                break;
+            case EIP202_RING_DMA_ALIGNMENT_16_BYTES:
+                Adapter_DMAResource_Alignment_Set(16);
+                break;
+            case EIP202_RING_DMA_ALIGNMENT_32_BYTES:
+                Adapter_DMAResource_Alignment_Set(32);
+                break;
+            default:
+                // Not supported, the alignment value cannot be determined
+                LOG_CRIT("AdapterLib_Ring_EIP202_DMA_Alignment_Determine: "
+                         "EIP-202 master interface HW data width "
+                         "(%d) is unsupported\n",
+                         AlignTo);
+                return false; // Error
+        } // switch
+    }
+    else
+    {
+#if ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT == 0
+        // The alignment value cannot be determined
+        return false; // Error
+#else
+        // Set the configured non-zero alignment value
+        Adapter_DMAResource_Alignment_Set(
+                ADAPTER_EIP202_DMA_ALIGNMENT_BYTE_COUNT);
+#endif
+    }
+#endif
+
+    Adapter_Ring_EIP202_DMA_Alignment_ByteCount =
+                            Adapter_DMAResource_Alignment_Get();
+
+    return true; // Success
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_DMA_Alignment_Get
+ *
+ * Get the required EIP-202 DMA alignment value
+ *
+ */
+inline static int
+AdapterLib_Ring_EIP202_DMA_Alignment_Get(void)
+{
+    return Adapter_Ring_EIP202_DMA_Alignment_ByteCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterLib_Ring_EIP202_DMAAddr_IsSane
+ *
+ * Validate the DMA address for the EIP-202 device
+ *
+ */
+inline static bool
+AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+        const EIP202_DeviceAddress_t * const DevAddr_p,
+        const char * BufferName_p)
+{
+#ifndef ADAPTER_EIP202_64BIT_DEVICE
+    // Check if 64-bit DMA address is used for EIP-202 configuration
+    // that supports 32-bit addresses only
+    if (DevAddr_p->UpperAddr)
+    {
+        LOG_CRIT("%s: failed, "
+                 "%s bus address (low/high 32 bits 0x%08x/0x%08x) too big\n",
+                 __func__,
+                 BufferName_p,
+                 DevAddr_p->Addr,
+                 DevAddr_p->UpperAddr);
+        return false;
+    }
+    else
+        return true;
+#else
+    IDENTIFIER_NOT_USED(DevAddr_p);
+    IDENTIFIER_NOT_USED(BufferName_p);
+    return true;
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+ * Implementation of the adapter_ring_eip202.h interface
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Adapter_Ring_EIP202_Configure
+ */
+void
+Adapter_Ring_EIP202_Configure(
+        const uint8_t HostDataWidth,
+        const uint8_t CF_Size,
+        const uint8_t RF_Size)
+{
+    Adapter_Ring_EIP202_HDW    = HostDataWidth;
+    Adapter_Ring_EIP202_CFSize = CF_Size;
+    Adapter_Ring_EIP202_RFSize = RF_Size;
+
+    Adapter_Ring_EIP202_Configured = true;
+}
+
+/*----------------------------------------------------------------------------
+ * Implementation of the adapter_rc_eip207.h interface
+ *
+ */
+
+#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+/*----------------------------------------------------------------------------
+ * Adapter_RC_EIP207_Configure
+ */
+void
+Adapter_RC_EIP207_Configure(
+        const bool fEnabledTRC,
+        const bool fEnabledARC4RC,
+        const bool fCombined)
+{
+    Adapter_RC_EIP207_Combined       = fCombined;
+    Adapter_RC_EIP207_TRC_Enabled    = fEnabledTRC;
+    Adapter_RC_EIP207_ARC4RC_Enabled = fEnabledARC4RC;
+
+    Adapter_RC_EIP207_Configured     = true;
+
+}
+#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+
+
+/*----------------------------------------------------------------------------
+ * Implementation of the adapter_pecdev_dma.h interface
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Capabilities_Get
+ */
+PEC_Status_t
+Adapter_PECDev_Capabilities_Get(
+        PEC_Capabilities_t * const Capabilities_p)
+{
+    uint8_t Versions[2];
+
+    if (Capabilities_p == NULL)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    memcpy(Capabilities_p, &CapabilitiesString, sizeof(CapabilitiesString));
+
+    // now fill in the number of rings.
+    {
+        Versions[0] = ADAPTER_EIP202_DEVICE_COUNT / 10;
+        Versions[1] = ADAPTER_EIP202_DEVICE_COUNT % 10;
+    }
+
+    {
+        char * p = Capabilities_p->szTextDescription;
+        int VerIndex = 0;
+        int i = 0;
+
+        if (p[sizeof(CapabilitiesString)-1] != 0)
+            return PEC_ERROR_INTERNAL;
+
+        while(p[i])
+        {
+            if (p[i] == '_')
+            {
+                if (VerIndex == sizeof(Versions)/sizeof(Versions[0]))
+                    return PEC_ERROR_INTERNAL;
+                if (Versions[VerIndex] > 9)
+                    p[i] = '?';
+                else
+                    p[i] = '0' + Versions[VerIndex++];
+            }
+
+            i++;
+        }
+    }
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+    Capabilities_p->SupportedFuncs = SHDevXS_SupportedFuncs_Get();
+#else
+    Capabilities_p->SupportedFuncs = EIP97_SupportedFuncs_Get();
+#endif
+    return PEC_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Control_Write
+ */
+PEC_Status_t
+Adapter_PECDev_CD_Control_Write(
+    PEC_CommandDescriptor_t *Command_p,
+    const PEC_PacketParams_t *PacketParams_p)
+{
+    IDENTIFIER_NOT_USED(Command_p);
+    IDENTIFIER_NOT_USED(PacketParams_p);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_RD_Status_Read
+ */
+PEC_Status_t
+Adapter_PECDev_RD_Status_Read(
+        const PEC_ResultDescriptor_t * const Result_p,
+        PEC_ResultStatus_t * const ResultStatus_p)
+{
+    unsigned int s;
+
+#ifdef ADAPTER_EIP202_STRICT_ARGS
+    if (ResultStatus_p == NULL)
+        return PEC_ERROR_BAD_PARAMETER;
+#endif
+
+    if (IOToken_ErrorCode_Get(Result_p->OutputToken_p, &s) < 0)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    // Translate the EIP-96 error codes to the PEC error codes
+    ResultStatus_p->errors =
+        BIT_MOVE(s,  0, 11) | // EIP-96 Packet length error
+        BIT_MOVE(s,  1, 17) | // EIP-96 Token error
+        BIT_MOVE(s,  2, 18) | // EIP-96 Bypass error
+        BIT_MOVE(s,  3,  9) | // EIP-96 Block size error
+        BIT_MOVE(s,  4, 16) | // EIP-96 Hash block size error.
+        BIT_MOVE(s,  5, 10) | // EIP-96 Invalid combo
+        BIT_MOVE(s,  6,  5) | // EIP-96 Prohibited algo
+        BIT_MOVE(s,  7, 19) | // EIP-96 Hash overflow
+#ifndef ADAPTER_EIP202_RING_TTL_ERROR_WA
+        BIT_MOVE(s,  8, 20) | // EIP-96 TTL/Hop limit underflow.
+#endif
+        BIT_MOVE(s,  9,  0) | // EIP-96 Authentication failed
+        BIT_MOVE(s, 10,  2) | // EIP-96 Sequence number check failed.
+        BIT_MOVE(s, 11,  8) | // EIP-96 SPI check failed.
+        BIT_MOVE(s, 12, 21) | // EIP-96 Incorrect checksum
+        BIT_MOVE(s, 12,  1) | // EIP-96 Pad verification.
+        BIT_MOVE(s, 14, 22);  // EIP-96 Timeout
+
+    // Translate the EIP-202 error codes to the PEC error codes
+    s = Result_p->Status1;
+    ResultStatus_p->errors  |=
+        BIT_MOVE(s, 21, 26) | // EIP-202 Buffer overflow
+        BIT_MOVE(s, 20, 25);  // EIP-202 Descriptor overflow
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Init
+ */
+PEC_Status_t
+Adapter_PECDev_Init(
+        const unsigned int InterfaceId,
+        const PEC_InitBlock_t * const InitBlock_p)
+{
+    Device_Handle_t CDR_Device, RDR_Device;
+    EIP202_Ring_Error_t res;
+    DMAResource_AddrPair_t PhysAddr_Pair;
+    unsigned int CDWordCount, RDWordCount; // Command and Result Descriptor size
+    unsigned int CDOffset, RDOffset; // Command and Result Descriptor Offsets
+    unsigned int RDTokenOffsWordCount;
+
+    IDENTIFIER_NOT_USED(InitBlock_p);
+
+    LOG_INFO("\n\t\t Adapter_PECDev_Init \n");
+
+    if (ADAPTER_EIP202_DEVICE_COUNT > ADAPTER_EIP202_DEVICE_COUNT_ACTUAL)
+    {
+        LOG_CRIT("Adapter_PECDev_Init: "
+                 "Adapter EIP-202 devices configuration is invalid\n");
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    CDR_Device = Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p);
+    RDR_Device = Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p);
+
+    if (CDR_Device == NULL || RDR_Device == NULL)
+        return PEC_ERROR_INTERNAL;
+    EIP202_ContinuousScatter[InterfaceId] = InitBlock_p->fContinuousScatter;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
+
+    // Reset both the CDR and RDR devives.
+    res = EIP202_CDR_Reset(CDR_IOArea + InterfaceId, CDR_Device);
+    if (res != EIP202_RING_NO_ERROR)
+        return PEC_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
+
+    res = EIP202_RDR_Reset(RDR_IOArea + InterfaceId, RDR_Device);
+    if (res != EIP202_RING_NO_ERROR)
+        return PEC_ERROR_INTERNAL;
+
+    // Determine the DMA buffer allocation alignment
+    if (!AdapterLib_Ring_EIP202_DMA_Alignment_Determine())
+        return PEC_ERROR_INTERNAL;
+
+#ifdef ADAPTER_EIP202_RING_LOCAL_CONFIGURE
+    // Configure the EIP-202 Ring Managers with configuration
+    // parameters obtained from local CDR device.
+    {
+      EIP202_Ring_Options_t options;
+
+      res = EIP202_CDR_Options_Get(CDR_Device, &options);
+      if (res != EIP202_RING_NO_ERROR)
+      {
+          LOG_CRIT("%s: EIP202_CDR_Options_Get failed, error %d\n",
+                   __func__,
+                   res);
+          return PEC_ERROR_INTERNAL;
+      }
+      Adapter_Ring_EIP202_Configure(options.HDW,
+                                    options.CF_Size,
+                                    options.RF_Size);
+    }
+#endif
+    // Determine required command and result descriptor size and offset
+    {
+        unsigned int ByteCount;
+
+        CDWordCount = EIP202_CD_CTRL_DATA_MAX_WORD_COUNT +
+                                            IOToken_InWordCount_Get();
+        ByteCount = MAX(AdapterLib_Ring_EIP202_DMA_Alignment_Get(),
+                        ADAPTER_EIP202_CD_OFFSET_BYTE_COUNT);
+        ByteCount = AdapterLib_Ring_EIP202_AlignForSize(
+                                CDWordCount * sizeof(uint32_t),
+                                ByteCount);
+        CDOffset = ByteCount / sizeof(uint32_t);
+
+        LOG_CRIT("%s: EIP-202 CD size/offset %d/%d (32-bit words)\n",
+                 __func__,
+                 CDWordCount,
+                 CDOffset);
+
+        if (Adapter_Ring_EIP202_HDW == 3)
+        {
+            RDTokenOffsWordCount = 8;
+        }
+        else
+        {
+            RDTokenOffsWordCount = EIP202_RD_CTRL_DATA_MAX_WORD_COUNT;
+        }
+        RDWordCount = RDTokenOffsWordCount +
+                                            IOToken_OutWordCount_Get();
+        ByteCount = MAX(AdapterLib_Ring_EIP202_DMA_Alignment_Get(),
+                        ADAPTER_EIP202_RD_OFFSET_BYTE_COUNT);
+        ByteCount = AdapterLib_Ring_EIP202_AlignForSize(
+                                RDWordCount * sizeof(uint32_t),
+                                ByteCount);
+        RDOffset = ByteCount / sizeof(uint32_t);
+
+        LOG_CRIT("%s: EIP-202 RD size/offset %d/%d (32-bit words)\n",
+                 __func__,
+                 RDWordCount,
+                 RDOffset);
+
+#ifndef ADAPTER_EIP202_SEPARATE_RINGS
+        {
+            unsigned int RDMaxTokenWordCount = RDOffset -
+                                           EIP202_RD_CTRL_DATA_MAX_WORD_COUNT;
+
+            if (CDWordCount > RDMaxTokenWordCount)
+            {
+                LOG_CRIT("%s: failed, EIP-202 CD (%d 32-bit words) "
+                         "exceeds max RD token space (%d 32-bit words)\n",
+                         __func__,
+                         CDWordCount,
+                         RDMaxTokenWordCount);
+                return PEC_ERROR_INTERNAL;
+            }
+        }
+#endif
+    }
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+    {
+        void *SABaseAddr;
+
+        SHDevXS_DMAPool_GetBase(&SABaseAddr);
+
+        LOG_INFO("Adapter_PECDev_Init: got SA base %p\n",SABaseAddr);
+
+        Adapter_AddrToWordPair(SABaseAddr,
+                               0,
+                               &EIP202_SABaseAddr,
+                               &EIP202_SABaseUpperAddr);
+    }
+#else
+    { // Set the SA pool base address.
+        int dmares;
+        Device_Handle_t Device;
+        DMAResource_Handle_t DMAHandle;
+        DMAResource_Properties_t DMAProperties;
+        DMAResource_AddrPair_t DMAAddr;
+
+        // Perform a dummy allocation in bank 1 to obtain the pool base
+        // address.
+        DMAProperties.Alignment = AdapterLib_Ring_EIP202_DMA_Alignment_Get();
+        DMAProperties.Bank      = ADAPTER_EIP202_BANK_SA;
+        DMAProperties.fCached   = false;
+        DMAProperties.Size      = ADAPTER_EIP202_TRANSFORM_RECORD_COUNT *
+                                    ADAPTER_EIP202_TRANSFORM_RECORD_BYTE_COUNT;
+
+        dmares = DMAResource_Alloc(DMAProperties, &DMAAddr, &DMAHandle);
+        if (dmares != 0)
+            return PEC_ERROR_INTERNAL;
+
+        // Derive the physical address from the DMA resource.
+        if (DMAResource_Translate(DMAHandle,
+                                  DMARES_DOMAIN_BUS,
+                                  &DMAAddr) < 0)
+        {
+            DMAResource_Release(DMAHandle);
+            return PEC_ERROR_INTERNAL;
+        }
+
+        Adapter_AddrToWordPair(DMAAddr.Address_p,
+                               0,
+                               &EIP202_SABaseAddr,
+                               &EIP202_SABaseUpperAddr);
+
+        // Set the cache base address.
+        Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
+        if (Device == NULL)
+        {
+            LOG_CRIT("Adapter_PECDev_UnInit: Could not find device\n");
+            return PEC_ERROR_INTERNAL;
+        }
+
+        LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
+
+        EIP207_RC_BaseAddr_Set(
+            Device,
+            EIP207_TRC_REG_BASE,
+            EIP207_RC_SET_NR_DEFAULT,
+            EIP202_SABaseAddr,
+            EIP202_SABaseUpperAddr);
+
+        // Release the DMA resource.
+        DMAResource_Release(DMAHandle);
+    }
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+    // Allocate the ring buffers(s).
+    {
+        int dmares;
+#ifdef ADAPTER_EIP202_SEPARATE_RINGS
+        unsigned int CDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * CDOffset;
+        unsigned int RDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * RDOffset;
+#else
+        unsigned int RDRByteCount = 4 * ADAPTER_EIP202_MAX_PACKETS * CDOffset +
+                                                ADAPTER_EIP202_CDR_BYTE_OFFSET;
+#endif
+
+        DMAResource_Properties_t RingProperties;
+        DMAResource_AddrPair_t RingHostAddr;
+
+        // used as uint32_t array
+        RingProperties.Alignment = AdapterLib_Ring_EIP202_DMA_Alignment_Get();
+        RingProperties.Bank      = ADAPTER_EIP202_BANK_RING;
+        RingProperties.fCached   = false;
+        RingProperties.Size      = RDRByteCount;
+
+        dmares = DMAResource_Alloc(RingProperties,
+                                   &RingHostAddr,
+                                   RDR_Handle + InterfaceId);
+        if (dmares != 0)
+            return PEC_ERROR_INTERNAL;
+
+#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
+        DMAResource_SwapEndianness_Set(RDR_Handle[InterfaceId],true);
+#endif
+
+        memset (RingHostAddr.Address_p, 0, RDRByteCount);
+
+#ifdef ADAPTER_EIP202_SEPARATE_RINGS
+
+        RingProperties.Size = CDRByteCount;
+
+        dmares = DMAResource_Alloc(RingProperties,
+                                   &RingHostAddr,
+                                   CDR_Handle + InterfaceId);
+        if (dmares != 0)
+        {
+            DMAResource_Release(RDR_Handle[InterfaceId]);
+            return PEC_ERROR_INTERNAL;
+        }
+
+#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
+        DMAResource_SwapEndianness_Set(CDR_Handle[InterfaceId], true);
+#endif
+
+        memset (RingHostAddr.Address_p, 0, CDRByteCount);
+
+#else
+        RingProperties.Size -= ADAPTER_EIP202_CDR_BYTE_OFFSET;
+        RingProperties.fCached = false;
+
+        {
+            uint8_t * Byte_p = (uint8_t*)RingHostAddr.Address_p;
+
+            Byte_p += ADAPTER_EIP202_CDR_BYTE_OFFSET;
+
+            RingHostAddr.Address_p = Byte_p;
+        }
+
+        dmares = DMAResource_CheckAndRegister(RingProperties,
+                                              RingHostAddr,
+                                              'R',
+                                              CDR_Handle + InterfaceId);
+        if (dmares != 0)
+        {
+            DMAResource_Release(RDR_Handle[InterfaceId]);
+            return PEC_ERROR_INTERNAL;
+        }
+
+#ifdef ADAPTER_EIP202_ARMRING_ENABLE_SWAP
+        DMAResource_SwapEndianness_Set(CDR_Handle[InterfaceId], true);
+#endif
+
+#endif
+
+        LOG_CRIT("%s: CDR/RDR byte count %d/%d, %s, CDR offset %d bytes\n",
+                 __func__,
+#ifdef ADAPTER_EIP202_SEPARATE_RINGS
+                 CDRByteCount,
+                 RDRByteCount,
+                 "non-overlapping",
+                 0);
+#else
+                 0,
+                 RDRByteCount,
+                 "overlapping",
+                 (int)ADAPTER_EIP202_CDR_BYTE_OFFSET);
+#endif
+    }
+
+    // Initialize the CDR and RDR devices
+    {
+        ZEROINIT(CDR_Settings);
+
+#ifdef ADAPTER_EIP202_RING_MANUAL_CONFIGURE
+        // Configure the EIP-202 Ring Managers with manually set
+        // configuration parameters
+        Adapter_Ring_EIP202_Configure(ADAPTER_EIP202_HOST_DATA_WIDTH,
+                                      ADAPTER_EIP202_CF_SIZE,
+                                      ADAPTER_EIP202_RF_SIZE);
+#endif
+
+        CDR_Settings.fATP        = (ADAPTER_EIP202_CDR_ATP_PRESENT > 0) ?
+                                                                true : false;
+        CDR_Settings.fATPtoToken = false;
+
+        CDR_Settings.Params.DataBusWidthWordCount = 1;
+
+        // Not used for CDR
+        CDR_Settings.Params.ByteSwap_DataType_Mask      = 0;
+        CDR_Settings.Params.ByteSwap_Packet_Mask        = 0;
+
+        // Enable endianess conversion for the RDR master interface
+        // if configured
+#ifdef ADAPTER_EIP202_CDR_BYTE_SWAP_ENABLE
+        CDR_Settings.Params.ByteSwap_Token_Mask         =
+        CDR_Settings.Params.ByteSwap_Descriptor_Mask    =
+                                            EIP202_RING_BYTE_SWAP_METHOD_32;
+#else
+        CDR_Settings.Params.ByteSwap_Token_Mask         = 0;
+        CDR_Settings.Params.ByteSwap_Descriptor_Mask    = 0;
+#endif
+
+        CDR_Settings.Params.Bufferability = 0;
+#ifdef ADAPTER_EIP202_64BIT_DEVICE
+        CDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DSCR_PTR;
+#else
+        CDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DISABLED;
+#endif
+        CDR_Settings.Params.RingSizeWordCount =
+                                        CDOffset * ADAPTER_EIP202_MAX_PACKETS;
+        CDR_Settings.Params.RingDMA_Handle = CDR_Handle[InterfaceId];
+
+#ifdef ADAPTER_EIP202_SEPARATE_RINGS
+        if (DMAResource_Translate(CDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
+                                  &PhysAddr_Pair) < 0)
+        {
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_INTERNAL;
+        }
+        Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0,
+                               &CDR_Settings.Params.RingDMA_Address.Addr,
+                               &CDR_Settings.Params.RingDMA_Address.UpperAddr);
+#else
+        if (DMAResource_Translate(RDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
+                                  &PhysAddr_Pair) < 0)
+        {
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_INTERNAL;
+        }
+        Adapter_AddrToWordPair(PhysAddr_Pair.Address_p,
+                               ADAPTER_EIP202_CDR_BYTE_OFFSET,
+                               &CDR_Settings.Params.RingDMA_Address.Addr,
+                               &CDR_Settings.Params.RingDMA_Address.UpperAddr);
+#endif
+
+        CDR_Settings.Params.DscrSizeWordCount = CDWordCount;
+        CDR_Settings.Params.DscrOffsWordCount = CDOffset;
+
+#ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+        if(Adapter_Ring_EIP202_Configured)
+        {
+            uint32_t cd_size_rndup;
+            int cfcount;
+
+            // Use configuration parameters received via
+            // the Ring 97 Configuration (adapter_ring_eip202.h) interface
+            if(CDR_Settings.Params.DscrOffsWordCount &
+                    ((1 << Adapter_Ring_EIP202_HDW) - 1))
+            {
+                LOG_CRIT("Adapter_PECDev_Init: Error, "
+                         "Command Descriptor Offset %d"
+                         " is not an integer multiple of Host Data Width %d\n",
+                         CDR_Settings.Params.DscrOffsWordCount,
+                         Adapter_Ring_EIP202_HDW);
+
+                Adapter_PECDev_UnInit(InterfaceId);
+                return PEC_ERROR_INTERNAL;
+            }
+
+            // Round up to the next multiple of HDW words
+            cd_size_rndup = (CDR_Settings.Params.DscrOffsWordCount +
+                                ((1 << Adapter_Ring_EIP202_HDW) - 1)) >>
+                                         Adapter_Ring_EIP202_HDW;
+
+            // Half of number of full descriptors that fit FIFO
+            // Note: Adapter_Ring_EIP202_CFSize is in HDW words
+            cfcount = (1<<(Adapter_Ring_EIP202_CFSize-1)) / cd_size_rndup;
+
+            // Check if command descriptor fits in fetch FIFO
+            if(cfcount <= 0)
+                cfcount = 1; // does not fit, adjust the count
+
+            // Note: cfcount must be also checked for not exceeding
+            //       max DMA length
+
+            // Convert to 32-bits word counts
+            CDR_Settings.Params.DscrFetchSizeWordCount =
+                (cfcount-1)* (cd_size_rndup << Adapter_Ring_EIP202_HDW);
+            CDR_Settings.Params.DscrThresholdWordCount =
+                     cfcount * (cd_size_rndup << Adapter_Ring_EIP202_HDW);
+        }
+        else
+#endif // #ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+        {
+            // Use default static (user-defined) configuration parameters
+#ifdef ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT
+            CDR_Settings.Params.DscrFetchSizeWordCount =
+                                    ADAPTER_EIP202_CDR_DSCR_FETCH_WORD_COUNT;
+#else
+            CDR_Settings.Params.DscrFetchSizeWordCount = CDOffset;
+#endif
+            CDR_Settings.Params.DscrThresholdWordCount =
+                                    ADAPTER_EIP202_CDR_DSCR_THRESH_WORD_COUNT;
+        }
+
+        LOG_CRIT("Adapter_PECDev_Init: CDR fetch size %d, threshold %d, "
+                 "HDW=%d, CFsize=%d\n",
+                 CDR_Settings.Params.DscrFetchSizeWordCount,
+                 CDR_Settings.Params.DscrThresholdWordCount,
+                 Adapter_Ring_EIP202_HDW,
+                 Adapter_Ring_EIP202_CFSize);
+
+        // CDR Interrupts will be enabled via the Event Mgmt API functions
+        CDR_Settings.Params.IntThresholdDscrCount = 0;
+        CDR_Settings.Params.IntTimeoutDscrCount = 0;
+        if ((CDR_Settings.Params.DscrFetchSizeWordCount /
+             CDR_Settings.Params.DscrOffsWordCount) >
+            (CDR_Settings.Params.DscrThresholdWordCount /
+             CDR_Settings.Params.DscrSizeWordCount))
+        {
+            LOG_CRIT("Adapter_PECDev_Init: CDR Threshold lower than fetch size"
+                     " incorrect setting\n");
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_BAD_PARAMETER;
+        }
+
+
+        LOG_INFO("\n\t\t\t EIP202_CDR_Init \n");
+
+        res = EIP202_CDR_Init(CDR_IOArea + InterfaceId,
+                              CDR_Device,
+                              &CDR_Settings);
+        if (res != EIP202_RING_NO_ERROR)
+        {
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_INTERNAL;
+        }
+    }
+
+    {
+        ZEROINIT(RDR_Settings);
+
+        RDR_Settings.Params.DataBusWidthWordCount = 1;
+
+        // Not used for RDR
+        RDR_Settings.Params.ByteSwap_DataType_Mask = 0;
+        RDR_Settings.Params.ByteSwap_Token_Mask = 0;
+
+        RDR_Settings.fContinuousScatter = InitBlock_p->fContinuousScatter;
+
+        // Enable endianess conversion for the RDR master interface
+        // if configured
+        RDR_Settings.Params.ByteSwap_Packet_Mask        = 0;
+#ifdef ADAPTER_EIP202_RDR_BYTE_SWAP_ENABLE
+        RDR_Settings.Params.ByteSwap_Descriptor_Mask    =
+                                            EIP202_RING_BYTE_SWAP_METHOD_32;
+#else
+        RDR_Settings.Params.ByteSwap_Descriptor_Mask    = 0;
+#endif
+
+        RDR_Settings.Params.Bufferability = 0;
+
+#ifdef ADAPTER_EIP202_64BIT_DEVICE
+        RDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DSCR_PTR;
+#else
+        RDR_Settings.Params.DMA_AddressMode = EIP202_RING_64BIT_DMA_DISABLED;
+#endif
+
+        RDR_Settings.Params.RingSizeWordCount =
+                                    RDOffset * ADAPTER_EIP202_MAX_PACKETS;
+
+        RDR_Settings.Params.RingDMA_Handle = RDR_Handle[InterfaceId];
+
+        if (DMAResource_Translate(RDR_Handle[InterfaceId], DMARES_DOMAIN_BUS,
+                                  &PhysAddr_Pair) < 0)
+        {
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_INTERNAL;
+        }
+        Adapter_AddrToWordPair(PhysAddr_Pair.Address_p, 0,
+                               &RDR_Settings.Params.RingDMA_Address.Addr,
+                               &RDR_Settings.Params.RingDMA_Address.UpperAddr);
+
+        RDR_Settings.Params.DscrSizeWordCount = RDWordCount;
+        RDR_Settings.Params.DscrOffsWordCount = RDOffset;
+        RDR_Settings.Params.TokenOffsetWordCount = RDTokenOffsWordCount;
+
+#ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+        if(Adapter_Ring_EIP202_Configured)
+        {
+            uint32_t rd_size_rndup;
+            int rfcount;
+
+            // Use configuration parameters received via
+            // the Ring 97 Configuration (adapter_ring_eip202.h) interface
+            if(RDR_Settings.Params.DscrOffsWordCount &
+                    ((1 << Adapter_Ring_EIP202_HDW) - 1))
+            {
+                LOG_CRIT("Adapter_PECDev_Init: Error, "
+                         "Result Descriptor Offset %d"
+                         " is not an integer multiple of Host Data Width %d\n",
+                         RDR_Settings.Params.DscrOffsWordCount,
+                         Adapter_Ring_EIP202_HDW);
+
+                Adapter_PECDev_UnInit(InterfaceId);
+                return PEC_ERROR_INTERNAL;
+            }
+
+            // Round up to the next multiple of HDW words
+            rd_size_rndup = (RDR_Settings.Params.DscrOffsWordCount +
+                                ((1 << Adapter_Ring_EIP202_HDW) - 1)) >>
+                                         Adapter_Ring_EIP202_HDW;
+
+            // Half of number of full descriptors that fit FIFO
+            // Note: Adapter_Ring_EIP202_RFSize is in HDW words
+            rfcount = (1 << (Adapter_Ring_EIP202_RFSize - 1)) / rd_size_rndup;
+
+            // Check if prepared result descriptor fits in fetch FIFO
+            if(rfcount <= 0)
+                rfcount = 1; // does not fit, adjust the count
+
+            // Note: rfcount must be also checked for not exceeding
+            //       max DMA length
+
+            // Convert to 32-bit words counts
+            RDR_Settings.Params.DscrFetchSizeWordCount =
+                (rfcount - 1) * (rd_size_rndup << Adapter_Ring_EIP202_HDW);
+            RDR_Settings.Params.DscrThresholdWordCount =
+                     rfcount * (rd_size_rndup << Adapter_Ring_EIP202_HDW);
+        }
+        else
+#endif // #ifndef ADAPTER_EIP202_AUTO_THRESH_DISABLE
+        {
+            // Use default static (user-defined) configuration parameters
+            RDR_Settings.Params.DscrFetchSizeWordCount =
+                                    ADAPTER_EIP202_RDR_DSCR_FETCH_WORD_COUNT;
+            RDR_Settings.Params.DscrThresholdWordCount =
+                                    ADAPTER_EIP202_RDR_DSCR_THRESH_WORD_COUNT;
+        }
+
+        LOG_CRIT("Adapter_PECDev_Init: RDR fetch size %d, threshold %d, "
+                 "RFsize=%d\n",
+                 RDR_Settings.Params.DscrFetchSizeWordCount,
+                 RDR_Settings.Params.DscrThresholdWordCount,
+                 Adapter_Ring_EIP202_RFSize);
+
+        // RDR Interrupts will be enabled via the Event Mgmt API functions
+        RDR_Settings.Params.IntThresholdDscrCount = 0;
+        RDR_Settings.Params.IntTimeoutDscrCount = 0;
+
+        if ((RDR_Settings.Params.DscrFetchSizeWordCount /
+             RDR_Settings.Params.DscrOffsWordCount) >
+            (RDR_Settings.Params.DscrThresholdWordCount /
+#ifdef ADAPTER_EIP202_64BIT_DEVICE
+             4 /* RDR prepared descriptor size for 64-bit */
+#else
+             2 /* RDR prepared descriptor size for 32-bit */
+#endif
+                ))
+        {
+            LOG_CRIT("Adapter_PECDev_Init: RDR Threshold lower than fetch size"
+                     " incorrect setting\n");
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_BAD_PARAMETER;
+        }
+        LOG_INFO("\n\t\t\t EIP202_RDR_Init \n");
+
+        res = EIP202_RDR_Init(RDR_IOArea + InterfaceId,
+                              RDR_Device,
+                              &RDR_Settings);
+        if (res != EIP202_RING_NO_ERROR)
+        {
+            Adapter_PECDev_UnInit(InterfaceId);
+            return PEC_ERROR_INTERNAL;
+        }
+    }
+
+    if (!AdapterLib_RD_OutTokens_Alloc(InterfaceId))
+    {
+        LOG_CRIT("Adapter_PECDev_Init: failed to allocate output tokens\n");
+        Adapter_PECDev_UnInit(InterfaceId);
+        return PEC_ERROR_INTERNAL; // Out of memory
+    }
+
+    AdapterLib_Ring_EIP202_Status_Report(InterfaceId);
+
+#ifdef ADAPTER_EIP202_ADD_INIT_DIAGNOSTICS
+    Adapter_Register_Dump();
+#endif
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_UnInit
+ */
+PEC_Status_t
+Adapter_PECDev_UnInit(
+        const unsigned int InterfaceId)
+{
+    Device_Handle_t CDR_Device, RDR_Device;
+
+    LOG_INFO("\n\t\t Adapter_PECDev_UnInit \n");
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    AdapterLib_Ring_EIP202_Status_Report(InterfaceId);
+
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+    {
+        // Make a last attempt to get rid of any remaining result descriptors
+        // belonging to unused scatter particles.
+        uint32_t DscrDoneCount,DscrCount;
+
+        LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Get \n");
+
+        EIP202_RDR_Descriptor_Get(RDR_IOArea + InterfaceId,
+                                 EIP202_RDR_Entries[InterfaceId],
+                                 ADAPTER_EIP202_MAX_LOGICDESCR,
+                                 ADAPTER_EIP202_MAX_LOGICDESCR,
+                                 &DscrDoneCount,
+                                 &DscrCount);
+    }
+#endif
+
+    AdapterLib_RD_OutTokens_Free(InterfaceId);
+
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+    {
+        // Reset the TRC base address to 0.
+        Device_Handle_t Device;
+
+        Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
+        if (Device == NULL)
+        {
+            LOG_CRIT("Adapter_PECDev_UnInit: Could not find device\n");
+            return PEC_ERROR_INTERNAL;
+        }
+
+        LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
+
+        EIP207_RC_BaseAddr_Set(
+            Device,
+            EIP207_TRC_REG_BASE,
+            EIP207_RC_SET_NR_DEFAULT,
+            0,
+            0);
+    }
+#endif
+#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+    CDR_Device = Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p);
+    RDR_Device = Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p);
+
+    if (CDR_Device == NULL || RDR_Device == NULL)
+        return PEC_ERROR_INTERNAL;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
+
+    EIP202_CDR_Reset(CDR_IOArea + InterfaceId,
+                    CDR_Device);
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
+
+    EIP202_RDR_Reset(RDR_IOArea + InterfaceId,
+                    RDR_Device);
+
+    if (RDR_Handle[InterfaceId] != NULL)
+    {
+        DMAResource_Release(RDR_Handle[InterfaceId]);
+        RDR_Handle[InterfaceId] = NULL;
+    }
+
+    if (CDR_Handle[InterfaceId] != NULL)
+    {
+        DMAResource_Release(CDR_Handle[InterfaceId]);
+        CDR_Handle[InterfaceId] = NULL;
+    }
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+    Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].RDR_IRQ_ID, NULL);
+    Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].CDR_IRQ_ID, NULL);
+#endif
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Resume
+ */
+int
+Adapter_PECDev_Resume(
+        const unsigned int InterfaceId)
+{
+    EIP202_Ring_Error_t res;
+
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_Init \n");
+    // Restore EIP-202 CDR
+    res = EIP202_CDR_Init(CDR_IOArea + InterfaceId,
+                          Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p),
+                          &CDR_Settings);
+    if (res != EIP202_RING_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP202_CDR_Init() error %d", __func__, res);
+        return -1;
+    }
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Init \n");
+    // Restore EIP-202 RDR
+    res = EIP202_RDR_Init(RDR_IOArea + InterfaceId,
+                          Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p),
+                          &RDR_Settings);
+    if (res != EIP202_RING_NO_ERROR)
+    {
+        LOG_CRIT("%s: EIP202_CDR_Init() error %d", __func__, res);
+        return -2;
+    }
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+    LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
+    // Restore EIP-207 Record Cache base address
+    EIP207_RC_BaseAddr_Set(
+        Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME),
+        EIP207_TRC_REG_BASE,
+        EIP207_RC_SET_NR_DEFAULT,
+        EIP202_SABaseAddr,
+        EIP202_SABaseUpperAddr);
+#endif
+#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+    // Restore RDR interrupt
+    if (EIP202_Interrupts[InterfaceId] & BIT_0)
+        Adapter_PECDev_Enable_ResultIRQ(InterfaceId);
+
+    // Restore CDR interrupt
+    if (EIP202_Interrupts[InterfaceId] & BIT_1)
+        Adapter_PECDev_Enable_CommandIRQ(InterfaceId);
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Suspend
+ */
+int
+Adapter_PECDev_Suspend(
+        const unsigned int InterfaceId)
+{
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+    // Disable RDR interrupt
+    if (EIP202_Interrupts[InterfaceId] & BIT_0)
+    {
+        Adapter_PECDev_Disable_ResultIRQ(InterfaceId);
+
+        // Remember that interrupt was enabled
+        EIP202_Interrupts[InterfaceId] |= BIT_0;
+    }
+
+    // Disable CDR interrupt
+    if (EIP202_Interrupts[InterfaceId] & BIT_1)
+    {
+        Adapter_PECDev_Disable_CommandIRQ(InterfaceId);
+
+        // Remember that interrupt was enabled
+        EIP202_Interrupts[InterfaceId] |= BIT_1;
+    }
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
+
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+    {
+        LOG_INFO("\n\t\t\t EIP207_RC_BaseAddr_Set \n");
+
+        // Reset the TRC base address to 0
+        EIP207_RC_BaseAddr_Set(
+            Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME),
+            EIP207_TRC_REG_BASE,
+            EIP207_RC_SET_NR_DEFAULT,
+            0,
+            0);
+    }
+#endif
+#endif // ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_Reset \n");
+
+    EIP202_CDR_Reset(CDR_IOArea + InterfaceId,
+                     Device_Find(EIP202_Devices[InterfaceId].CDR_DeviceName_p));
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Reset \n");
+
+    EIP202_RDR_Reset(RDR_IOArea + InterfaceId,
+                     Device_Find(EIP202_Devices[InterfaceId].RDR_DeviceName_p));
+
+    return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SA_Prepare
+ */
+PEC_Status_t
+Adapter_PECDev_SA_Prepare(
+        const DMABuf_Handle_t SAHandle,
+        const DMABuf_Handle_t StateHandle,
+        const DMABuf_Handle_t ARC4Handle)
+{
+    DMAResource_Handle_t SA_DMAHandle;
+
+    IDENTIFIER_NOT_USED(StateHandle.p);
+    IDENTIFIER_NOT_USED(ARC4Handle.p);
+
+    if (DMABuf_Handle_IsSame(&SAHandle, &DMABuf_NULLHandle))
+        return PEC_ERROR_BAD_PARAMETER;
+    else
+    {
+        DMAResource_Record_t * Rec_p;
+
+        SA_DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(SAHandle);
+        Rec_p = DMAResource_Handle2RecordPtr(SA_DMAHandle);
+
+        if (Rec_p == NULL)
+            return PEC_ERROR_INTERNAL;
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+        if (Rec_p->Props.Bank != ADAPTER_EIP202_BANK_SA)
+        {
+            LOG_CRIT("PEC_SA_Register: Invalid bank for SA\n");
+            return PEC_ERROR_BAD_PARAMETER;
+        }
+#endif
+
+#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
+        {
+            uint32_t FirstWord = DMAResource_Read32(SA_DMAHandle, 0);
+            // Register in the DMA resource record whether the transform
+            // is large.
+            if ( (FirstWord & ADAPTER_EIP202_TR_ISLARGE) != 0)
+            {
+                Rec_p->fIsLargeTransform = true;
+                DMAResource_Write32(SA_DMAHandle,
+                                    0,
+                                    FirstWord & ~ADAPTER_EIP202_TR_ISLARGE);
+                // Clear that bit in the SA record itself.
+            }
+            else
+            {
+                Rec_p->fIsLargeTransform = false;
+            }
+        }
+#endif
+
+        Rec_p->fIsNewSA = true;
+    }
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SA_Remove
+ */
+PEC_Status_t
+Adapter_PECDev_SA_Remove(
+        const DMABuf_Handle_t SAHandle,
+        const DMABuf_Handle_t StateHandle,
+        const DMABuf_Handle_t ARC4Handle)
+{
+    IDENTIFIER_NOT_USED(StateHandle.p);
+
+    if (DMABuf_Handle_IsSame(&SAHandle, &DMABuf_NULLHandle))
+        return PEC_ERROR_BAD_PARAMETER;
+
+#ifdef ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+    // Invalidate the record in the EIP-207 Transform Record Cache
+    // or/and ARC4 State Record Cache
+    // Not configured = disabled
+    if (Adapter_RC_EIP207_Configured)
+    {
+#ifndef ADAPTER_EIP202_USE_SHDEVXS
+        Device_Handle_t Device;
+
+        Device = Device_Find(ADAPTER_EIP202_GLOBAL_DEVICE_NAME);
+        if (Device == NULL)
+        {
+            LOG_CRIT("Adapter_PECDev_SA_Remove: Could not find device\n");
+            return PEC_ERROR_INTERNAL;
+        }
+#endif
+
+        if (Adapter_RC_EIP207_TRC_Enabled)
+        {
+            EIP202_DeviceAddress_t DMA_Addr;
+
+            Adapter_GetPhysAddr(SAHandle, &DMA_Addr);
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+            DMA_Addr.Addr -= EIP202_SABaseAddr;
+#endif
+
+            // Invalidate the SA Record in the TRC
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+            LOG_INFO("\n\t\t\t SHDevXS_TRC_Record_Invalidate \n");
+
+            SHDevXS_TRC_Record_Invalidate(DMA_Addr.Addr);
+#else
+            LOG_INFO("\n\t\t\t EIP207_RC_Record_Update \n");
+
+            EIP207_RC_Record_Update(
+                    Device,
+                    EIP207_TRC_REG_BASE,
+                    EIP207_RC_SET_NR_DEFAULT,
+                    DMA_Addr.Addr,
+                    EIP207_RC_CMD_SET_BITS,
+                    EIP207_RC_REG_DATA_BYTE_OFFSET - 3 * sizeof(uint32_t),
+                    EIP207_RC_HDR_WORD_3_RELOAD_BIT);
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+        }
+
+        if (!DMABuf_Handle_IsSame(&ARC4Handle, &DMABuf_NULLHandle) &&
+            Adapter_RC_EIP207_ARC4RC_Enabled)
+        {
+            EIP202_DeviceAddress_t DMA_Addr;
+
+            Adapter_GetPhysAddr(ARC4Handle, &DMA_Addr);
+
+            // Invalidate the ARC4 State record in the TRC or ARC4RC
+#ifdef ADAPTER_EIP202_USE_SHDEVXS
+            LOG_INFO("\n\t\t\t SHDevXS_ARC4RC_Record_Invalidate \n");
+
+            SHDevXS_ARC4RC_Record_Invalidate(DMA_Addr.Addr);
+#else
+            LOG_INFO("\n\t\t\t EIP207_RC_Record_Update \n");
+
+            EIP207_RC_Record_Update(
+                    Device,
+                    EIP207_ARC4RC_REG_BASE,
+                    EIP207_RC_SET_NR_DEFAULT,
+                    DMA_Addr.Addr,
+                    EIP207_RC_CMD_SET_BITS,
+                    EIP207_RC_REG_DATA_BYTE_OFFSET - 3 * sizeof(uint32_t),
+                    EIP207_RC_HDR_WORD_3_RELOAD_BIT);
+#endif // ADAPTER_EIP202_USE_SHDEVXS
+        }
+    }
+#else
+    IDENTIFIER_NOT_USED(ARC4Handle.p);
+#endif // ADAPTER_EIP202_RC_DIRECT_INVALIDATE_SUPPORT
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_GetFreeSpace
+ */
+unsigned int
+Adapter_PECDev_GetFreeSpace(
+        const unsigned int InterfaceId)
+{
+    unsigned int FreeCDR, FreeRDR, FilledCDR, FilledRDR;
+    EIP202_Ring_Error_t res;
+
+    LOG_INFO("\n\t\t Adapter_PECDev_GetFreeSpace \n");
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
+
+    res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
+                                  &FilledCDR);
+    if (res != EIP202_RING_NO_ERROR)
+        return 0;
+
+    if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
+        return 0;
+
+    FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
+
+    if (EIP202_ContinuousScatter[InterfaceId])
+    {
+        return FreeCDR;
+    }
+    else
+    {
+        LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
+
+        res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
+                                       &FilledRDR);
+        if (res != EIP202_RING_NO_ERROR)
+            return 0;
+
+        if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
+            return 0;
+
+        FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
+
+        return MIN(FreeCDR, FreeRDR);
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_PacketPut
+ */
+PEC_Status_t
+Adapter_PECDev_Packet_Put(
+        const unsigned int InterfaceId,
+        const PEC_CommandDescriptor_t * Commands_p,
+        const unsigned int CommandsCount,
+        unsigned int * const PutCount_p)
+{
+    unsigned int CmdLp;
+#ifdef ADAPTER_EIP202_STRICT_ARGS
+    unsigned int FreeCDR,FreeRDR;
+#endif
+    unsigned int FilledCDR, FilledRDR, CDRIndex=0, RDRIndex=0;
+    unsigned int Submitted = 0;
+    EIP202_Ring_Error_t res;
+    EIP202_CDR_Control_t CDR_Control;
+    EIP202_RDR_Prepared_Control_t RDR_Control;
+
+    LOG_INFO("\n\t\t Adapter_PECDev_Packet_Put \n");
+
+    *PutCount_p = 0;
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+#ifdef ADAPTER_EIP202_STRICT_ARGS
+    LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
+
+    res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
+                                  &FilledCDR);
+    if (res != EIP202_RING_NO_ERROR)
+        return PEC_ERROR_INTERNAL;
+
+    if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
+        return PEC_ERROR_INTERNAL;
+
+    FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
+
+    if (!EIP202_ContinuousScatter[InterfaceId])
+    {
+        res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
+                                       &FilledRDR);
+        if (res != EIP202_RING_NO_ERROR)
+            return PEC_ERROR_INTERNAL;
+
+        if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
+        return PEC_ERROR_INTERNAL;
+
+        FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
+        FreeRDR = MIN(ADAPTER_EIP202_MAX_LOGICDESCR, FreeRDR);
+    }
+    else
+    {
+        FreeRDR = 1;
+    }
+    FreeCDR = MIN(ADAPTER_EIP202_MAX_LOGICDESCR, FreeCDR);
+#endif
+
+    for (CmdLp = 0; CmdLp < CommandsCount; CmdLp++)
+    {
+        uint8_t TokenWordCount;
+        EIP202_DeviceAddress_t SA_PhysAddr;
+
+#ifdef ADAPTER_EIP202_STRICT_ARGS
+        if (CDRIndex == FreeCDR || (!EIP202_ContinuousScatter[InterfaceId] && RDRIndex == FreeRDR))
+            break; // Run out of free descriptors in any of the rings.
+#endif
+
+        if (!Commands_p[CmdLp].InputToken_p)
+        {
+            LOG_CRIT("Adapter_PECDev_Packet_Put: failed, missing input token "
+                     "for command descriptor %d\n",
+                     CmdLp);
+            return PEC_ERROR_BAD_PARAMETER;
+        }
+
+        // Prepare (first) descriptor, except for source pointer/size.
+        EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketByteCount =
+                                            Commands_p[CmdLp].SrcPkt_ByteCount;
+
+        if (DMABuf_Handle_IsSame(&Commands_p[CmdLp].Token_Handle,
+                                 &DMABuf_NULLHandle))
+        {
+            TokenWordCount = 0;
+        }
+        else
+        {
+            // Look-aside use case. token is created by the caller
+            if (Commands_p[CmdLp].Token_WordCount > 255)
+                return PEC_ERROR_INTERNAL;
+
+            TokenWordCount = (uint8_t)Commands_p[CmdLp].Token_WordCount;
+        }
+
+        CDR_Control.TokenWordCount = TokenWordCount;
+
+        Adapter_GetPhysAddr(Commands_p[CmdLp].Token_Handle,
+              &(EIP202_CDR_Entries[InterfaceId][CDRIndex].TokenDataAddr));
+
+        if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                &EIP202_CDR_Entries[InterfaceId][CDRIndex].TokenDataAddr,
+                "token buffer"))
+            return PEC_ERROR_INTERNAL;
+
+        CDR_Control.fFirstSegment = true;
+        CDR_Control.fLastSegment  = false;
+        CDR_Control.fForceEngine = (Commands_p[CmdLp].Control2 & BIT_5) != 0;
+        CDR_Control.EngineId = Commands_p[CmdLp].Control2 & MASK_5_BITS;
+
+        EIP202_CDR_Entries[InterfaceId][CDRIndex].Token_p =
+                                            Commands_p[CmdLp].InputToken_p;
+
+        Adapter_GetPhysAddr(Commands_p[CmdLp].SA_Handle1, &SA_PhysAddr);
+
+        if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO ||
+            SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
+        {
+            DMAResource_Handle_t DMAHandle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(
+                                        Commands_p[CmdLp].SA_Handle1);
+            DMAResource_Record_t * Rec_p =
+                                    DMAResource_Handle2RecordPtr(DMAHandle);
+            if (Rec_p == NULL)
+                return PEC_ERROR_INTERNAL;
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+            if (Rec_p->Props.Bank != ADAPTER_EIP202_BANK_SA)
+            {
+                LOG_CRIT("PEC_Packet_Put: Invalid bank for SA\n");
+                return PEC_ERROR_BAD_PARAMETER;
+            }
+#endif
+
+            if (IOToken_SAReuse_Update(!Rec_p->fIsNewSA,
+                                       Commands_p[CmdLp].InputToken_p) < 0)
+                return PEC_ERROR_INTERNAL;
+
+            if (Rec_p->fIsNewSA)
+                Rec_p->fIsNewSA = false;
+        }
+
+#ifdef ADAPTER_EIP202_USE_POINTER_TYPES
+        if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_LO ||
+            SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
+        {
+#ifndef ADAPTER_EIP202_USE_LARGE_TRANSFORM_DISABLE
+            DMAResource_Handle_t DMAHandle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(
+                                        Commands_p[CmdLp].SA_Handle1);
+            DMAResource_Record_t * Rec_p =
+                            DMAResource_Handle2RecordPtr(DMAHandle);
+
+            if (Rec_p->fIsLargeTransform)
+                SA_PhysAddr.Addr |= ADAPTER_EIP202_TR_LARGE_ADDRESS;
+            else
+#endif
+                SA_PhysAddr.Addr |= ADAPTER_EIP202_TR_ADDRESS;
+        }
+#endif
+
+#ifdef ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+#ifdef ADAPTER_EIP202_RC_DMA_BANK_SUPPORT
+        if (SA_PhysAddr.Addr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS ||
+            SA_PhysAddr.UpperAddr != ADAPTER_EIP202_DUMMY_DMA_ADDRESS_HI)
+            SA_PhysAddr.Addr -= EIP202_SABaseAddr;
+
+        SA_PhysAddr.UpperAddr = 0;
+#endif // ADAPTER_EIP202_RC_DMA_BANKS_SUPPORT
+#endif // ADAPTER_EIP202_DMARESOURCE_BANKS_ENABLE
+
+        EIP202_CDR_Entries[InterfaceId][CDRIndex].ContextDataAddr = SA_PhysAddr;
+
+        if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(&SA_PhysAddr, "SA buffer"))
+            return PEC_ERROR_INTERNAL;
+
+        {
+            IOToken_PhysAddr_t tkn_pa;
+
+            tkn_pa.Lo = SA_PhysAddr.Addr;
+            tkn_pa.Hi = SA_PhysAddr.UpperAddr;
+
+            if (IOToken_SAAddr_Update(&tkn_pa,
+                                      Commands_p[CmdLp].InputToken_p) < 0)
+                return PEC_ERROR_INTERNAL;
+        }
+
+        RDR_Control.fFirstSegment           = true;
+        RDR_Control.fLastSegment            = false;
+        RDR_Control.ExpectedResultWordCount = 0;
+
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+        {
+            unsigned int GatherParticles;
+            unsigned int ScatterParticles;
+            unsigned int RequiredCDR, RequiredRDR;
+            unsigned int i;
+            unsigned int GatherByteCount;
+
+            PEC_SGList_GetCapacity(Commands_p[CmdLp].SrcPkt_Handle,
+                                   &GatherParticles);
+            if (EIP202_ContinuousScatter[InterfaceId])
+                ScatterParticles = 1;
+            else
+                PEC_SGList_GetCapacity(Commands_p[CmdLp].DstPkt_Handle,
+                                       &ScatterParticles);
+
+            if (GatherParticles == 0)
+                RequiredCDR = 1;
+            else
+                RequiredCDR = GatherParticles;
+
+            if (ScatterParticles == 0)
+                RequiredRDR = 1;
+            else
+                RequiredRDR = ScatterParticles;
+
+#ifndef ADAPTER_EIP202_SEPARATE_RINGS
+            // If using overlapping rings, require an equal number of CDR
+            // and RDR entries for the packet, the maximum of both.
+            RequiredCDR = MAX(RequiredCDR,RequiredRDR);
+            RequiredRDR = RequiredCDR;
+#endif
+            /* Check whether it will fit into the rings and the
+             * prepared descriptor arrays.*/
+#ifdef ADAPTER_EIP202_STRICT_ARGS
+            if (CDRIndex + RequiredCDR > FreeCDR ||
+                RDRIndex + RequiredRDR > FreeRDR)
+                break;
+#endif
+
+            if (GatherParticles > 0)
+            {
+                GatherByteCount = Commands_p[CmdLp].SrcPkt_ByteCount;
+                for (i=0; i<GatherParticles; i++)
+                {
+                    DMABuf_Handle_t ParticleHandle;
+                    uint8_t * DummyPtr;
+                    unsigned int ParticleSize;
+
+                    PEC_SGList_Read(Commands_p[CmdLp].SrcPkt_Handle,
+                                    i,
+                                    &ParticleHandle,
+                                    &ParticleSize,
+                                    &DummyPtr);
+
+                    Adapter_GetPhysAddr(ParticleHandle,
+                      &(EIP202_CDR_Entries[InterfaceId][CDRIndex+i].SrcPacketAddr));
+
+                    if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                            &EIP202_CDR_Entries[InterfaceId][CDRIndex+i].SrcPacketAddr,
+                            "source packet buffer"))
+                        return PEC_ERROR_INTERNAL;
+
+                    if (ParticleSize > GatherByteCount)
+                        ParticleSize = GatherByteCount;
+                    GatherByteCount -= ParticleSize;
+                    // Limit the total size of the gather particles to the
+                    // actual packet length.
+
+                    CDR_Control.fLastSegment = (RequiredCDR == i + 1);
+                    CDR_Control.SegmentByteCount = ParticleSize;
+                    EIP202_CDR_Entries[InterfaceId][CDRIndex+i].ControlWord =
+                        EIP202_CDR_Write_ControlWord(&CDR_Control);
+                    CDR_Control.fFirstSegment = false;
+                    CDR_Control.TokenWordCount = 0;
+                }
+            }
+            else
+            { /* No gather, use single source buffer */
+
+                Adapter_GetPhysAddr(Commands_p[CmdLp].SrcPkt_Handle,
+                 &(EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr));
+
+                if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                        &EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr,
+                        "source packet buffer"))
+                    return PEC_ERROR_INTERNAL;
+
+                CDR_Control.fLastSegment = (RequiredCDR == 1);
+                CDR_Control.SegmentByteCount =
+                    Commands_p[CmdLp].SrcPkt_ByteCount;
+                EIP202_CDR_Entries[InterfaceId][CDRIndex].ControlWord =
+                    EIP202_CDR_Write_ControlWord(&CDR_Control);
+
+                CDR_Control.fFirstSegment = false;
+                CDR_Control.TokenWordCount = 0;
+                i = 1;
+            }
+
+            /* Add any dummy segments for overlapping rings */
+            for ( ; i<RequiredCDR; i++)
+            {
+
+                CDR_Control.fLastSegment = (RequiredCDR == i + 1);
+                CDR_Control.SegmentByteCount = 0;
+                EIP202_CDR_Entries[InterfaceId][CDRIndex+i].ControlWord =
+                    EIP202_CDR_Write_ControlWord(&CDR_Control);
+            }
+
+            if (!EIP202_ContinuousScatter[InterfaceId])
+            {
+                if (ScatterParticles > 0)
+                {
+                    for (i=0; i<ScatterParticles; i++)
+                    {
+                        DMABuf_Handle_t ParticleHandle;
+                        uint8_t * DummyPtr;
+                        unsigned int ParticleSize;
+
+                        PEC_SGList_Read(Commands_p[CmdLp].DstPkt_Handle,
+                                        i,
+                                        &ParticleHandle,
+                                        &ParticleSize,
+                                        &DummyPtr);
+
+                        Adapter_GetPhysAddr(ParticleHandle,
+                                            &(EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].DstPacketAddr));
+
+                        if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                                &EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].DstPacketAddr,
+                                "destination packet buffer"))
+                            return PEC_ERROR_INTERNAL;
+
+                        RDR_Control.fLastSegment = (RequiredRDR == i + 1);
+                        RDR_Control.PrepSegmentByteCount = ParticleSize;
+                        EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].PrepControlWord =
+                            EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
+
+                        RDR_Control.fFirstSegment = false;
+                    }
+                }
+                else
+                { /* No scatter, use single destination buffer */
+                    DMAResource_Handle_t *DMAHandle =
+                    Adapter_DMABuf_Handle2DMAResourceHandle(
+                        Commands_p[CmdLp].DstPkt_Handle);
+                    DMAResource_Record_t * Rec_p;
+
+                    if (DMAResource_IsValidHandle(DMAHandle))
+                        Rec_p  = DMAResource_Handle2RecordPtr(DMAHandle);
+                    else
+                        Rec_p = NULL;
+
+                    // Check if NULL packet pointers are allowed
+                    // for record invalidation commands
+#ifndef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+                    if (Rec_p == NULL)
+                        return PEC_ERROR_INTERNAL;
+#endif
+
+                    Adapter_GetPhysAddr(Commands_p[CmdLp].DstPkt_Handle,
+                                        &(EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr));
+
+                    if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                      &EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr,
+                      "destination packet buffer"))
+                    return PEC_ERROR_INTERNAL;
+
+                    RDR_Control.fLastSegment = (RequiredRDR==1);
+
+#ifdef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+                    // For NULL packet pointers only, record cache invalidation
+                    if (Rec_p == NULL)
+                        RDR_Control.PrepSegmentByteCount = 0;
+                    else
+#endif
+                        RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
+
+                    EIP202_RDR_Prepared[InterfaceId][RDRIndex].PrepControlWord =
+                        EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
+
+                    RDR_Control.fFirstSegment = false;
+                    i = 1;
+                }
+
+                /* Add any dummy segments for overlapping rings */
+                for ( ; i<RequiredRDR; i++)
+                {
+                    RDR_Control.fLastSegment = (RequiredRDR == i + 1);
+                    RDR_Control.PrepSegmentByteCount = 0;
+                    EIP202_RDR_Prepared[InterfaceId][RDRIndex+i].PrepControlWord =
+                        EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
+                }
+                RDRIndex += RequiredRDR;
+            }
+            CDRIndex += RequiredCDR;
+        }
+#else
+        {
+            // Prepare source and destination buffer in non-SG case.
+            DMAResource_Handle_t *DMAHandle =
+                Adapter_DMABuf_Handle2DMAResourceHandle(
+                    Commands_p[CmdLp].DstPkt_Handle);
+            DMAResource_Record_t * Rec_p;
+
+            if (DMAResource_IsValidHandle(DMAHandle))
+                Rec_p  = DMAResource_Handle2RecordPtr(DMAHandle);
+            else
+                Rec_p = NULL;
+
+            // Check if NULL packet pointers are allowed
+            // for record invalidation commands
+#ifndef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+            if (Rec_p == NULL)
+                return PEC_ERROR_INTERNAL;
+#endif
+
+            Adapter_GetPhysAddr(Commands_p[CmdLp].SrcPkt_Handle,
+                 &(EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr));
+
+            if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                  &EIP202_CDR_Entries[InterfaceId][CDRIndex].SrcPacketAddr,
+                  "source packet buffer"))
+                return PEC_ERROR_INTERNAL;
+
+            CDR_Control.fLastSegment     = true;
+            CDR_Control.SegmentByteCount = Commands_p[CmdLp].SrcPkt_ByteCount;
+
+            EIP202_CDR_Entries[InterfaceId][CDRIndex].ControlWord =
+                                EIP202_CDR_Write_ControlWord(&CDR_Control);
+
+            if (!EIP202_ContinuousScatter[InterfaceId])
+            {
+                Adapter_GetPhysAddr(Commands_p[CmdLp].DstPkt_Handle,
+                                    &(EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr));
+
+                if (!AdapterLib_Ring_EIP202_DMAAddr_IsSane(
+                        &EIP202_RDR_Prepared[InterfaceId][RDRIndex].DstPacketAddr,
+                        "destination packet buffer"))
+                    return PEC_ERROR_INTERNAL;
+
+                RDR_Control.fLastSegment = true;
+
+#ifdef ADAPTER_EIP202_INVALIDATE_NULL_PKT_POINTER
+                // For NULL packet pointers only, record cache invalidation
+                if (Rec_p == NULL)
+                    RDR_Control.PrepSegmentByteCount = 0;
+                else
+#endif
+                    RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
+
+                EIP202_RDR_Prepared[InterfaceId][RDRIndex].PrepControlWord =
+                    EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
+
+                RDRIndex +=1;
+            }
+            CDRIndex +=1;
+        }
+#endif
+        *PutCount_p += 1;
+    } // for, CommandsCount, CmdLp
+
+
+    if (!EIP202_ContinuousScatter[InterfaceId])
+    {
+        LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Prepare \n");
+        res = EIP202_RDR_Descriptor_Prepare(RDR_IOArea + InterfaceId,
+                                            EIP202_RDR_Prepared[InterfaceId],
+                                            RDRIndex,
+                                            &Submitted,
+                                            &FilledRDR);
+        if (res != EIP202_RING_NO_ERROR || Submitted != RDRIndex)
+        {
+            LOG_CRIT("Adapter_PECDev_Packet_Put: writing prepared descriptors"
+                     "error code %d count=%d expected=%d\n",
+                     res, Submitted, RDRIndex);
+            return PEC_ERROR_INTERNAL;
+        }
+    }
+    LOG_INFO("\n\t\t\t EIP202_CDR_Descriptor_Put \n");
+
+    res = EIP202_CDR_Descriptor_Put(CDR_IOArea + InterfaceId,
+                                   EIP202_CDR_Entries[InterfaceId],
+                                   CDRIndex,
+                                   &Submitted,
+                                   &FilledCDR);
+    if (res != EIP202_RING_NO_ERROR || Submitted != CDRIndex)
+    {
+        LOG_CRIT("Adapter_PECDev_Packet_Put: writing command descriptors"
+                 "error code %d count=%d expected=%d\n",
+                 res, Submitted, CDRIndex);
+        return PEC_ERROR_INTERNAL;
+    }
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Packet_Get
+ */
+PEC_Status_t
+Adapter_PECDev_Packet_Get(
+        const unsigned int InterfaceId,
+        PEC_ResultDescriptor_t * Results_p,
+        const unsigned int ResultsLimit,
+        unsigned int * const GetCount_p)
+{
+    unsigned int ResLp;
+    unsigned int DscrCount;
+    unsigned int DscrDoneCount;
+    unsigned int ResIndex;
+
+    EIP202_Ring_Error_t res;
+
+    LOG_INFO("\n\t\t Adapter_PECDev_Packet_Get \n");
+
+    *GetCount_p = 0;
+
+    if (ResultsLimit == 0)
+        return PEC_STATUS_OK;
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Descriptor_Get \n");
+
+    // Assume that we do get the requested number of descriptors
+    // as they were reported available.
+    res = EIP202_RDR_Descriptor_Get(RDR_IOArea + InterfaceId,
+                                    EIP202_RDR_Entries[InterfaceId],
+                                    ResultsLimit, // Max number of packets.
+                                    ADAPTER_EIP202_MAX_LOGICDESCR,
+                                    &DscrDoneCount,
+                                    &DscrCount);
+    if (res != EIP202_RING_NO_ERROR)
+        return PEC_ERROR_INTERNAL;
+
+    ResIndex = 0;
+    for (ResLp = 0; ResLp < ResultsLimit; ResLp++)
+    {
+        EIP202_RDR_Result_Control_t ControlWord;
+        bool fEncounteredFirst = false;
+
+        if (ResIndex >= DscrDoneCount)
+            break;
+
+        for (;;)
+        {
+            LOG_INFO("\n\t\t\t EIP202_RDR_Read_Processed_ControlWord \n");
+
+            EIP202_RDR_Read_Processed_ControlWord(
+                                EIP202_RDR_Entries[InterfaceId] + ResIndex,
+                                &ControlWord,
+                                NULL);
+
+            if ( ControlWord.fFirstSegment)
+            {
+                fEncounteredFirst = true;
+                Results_p[ResLp].NumParticles = 0;
+            }
+            Results_p[ResLp].NumParticles++;
+
+            if ( ControlWord.fLastSegment && fEncounteredFirst)
+                break; // Last segment of packet, only valid when
+                       // first segment was encountered.
+            ResIndex++;
+
+            // There may be unused scatter particles after the last segment
+            // that must be skipped.
+            if (ResIndex >= DscrDoneCount)
+                return PEC_STATUS_OK;
+        }
+
+        // Presence of Output Token placeholder is optional
+        if (Results_p[ResLp].OutputToken_p)
+        {
+            // Copy Output Token from EIP-202 to PEC result descriptor
+            memcpy(Results_p[ResLp].OutputToken_p,
+                   EIP202_RDR_Entries[InterfaceId][ResIndex].Token_p,
+                   IOToken_OutWordCount_Get() * sizeof (uint32_t));
+
+            IOToken_PacketLegth_Get(Results_p[ResLp].OutputToken_p,
+                                    &Results_p[ResLp].DstPkt_ByteCount);
+
+            IOToken_BypassLegth_Get(Results_p[ResLp].OutputToken_p,
+                                    &Results_p[ResLp].Bypass_WordCount);
+        }
+
+        // Copy the first EIP-202 result descriptor word, contains
+        // - Particle byte count,
+        // - Buffer overflow (BIT_21) and Descriptor overflow (BIT_20) errors
+        // - First segment (BIT_23) and Last segment (BIT_22) indicators
+        // - Descriptor overflow word count if BIT_20 is set
+        Results_p[ResLp].Status1 =
+              EIP202_RDR_Entries[InterfaceId][ResIndex].ProcControlWord;
+
+        *GetCount_p += 1;
+        ResIndex++;
+    }
+
+    return PEC_STATUS_OK;
+}
+
+
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_TestSG
+ */
+bool
+Adapter_PECDev_TestSG(
+    const unsigned int InterfaceId,
+    const unsigned int GatherParticleCount,
+    const unsigned int ScatterParticleCount)
+{
+    unsigned int GCount = GatherParticleCount;
+    unsigned int SCount = ScatterParticleCount;
+    unsigned int FreeCDR, FreeRDR, FilledCDR, FilledRDR;
+    EIP202_Ring_Error_t res;
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return false;
+
+    if (GCount == 0)
+        GCount = 1;
+
+    if (SCount == 0)
+        SCount = 1;
+
+#ifndef ADAPTER_EIP202_SEPARATE_RINGS
+    GCount = MAX(GCount, SCount);
+    SCount = GCount;
+#endif
+
+    if (GCount > ADAPTER_EIP202_MAX_LOGICDESCR ||
+        SCount > ADAPTER_EIP202_MAX_LOGICDESCR)
+        return false;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Get \n");
+
+    res = EIP202_CDR_FillLevel_Get(CDR_IOArea + InterfaceId,
+                                  &FilledCDR);
+    if (res != EIP202_RING_NO_ERROR)
+        return false;
+
+    if (FilledCDR > ADAPTER_EIP202_MAX_PACKETS)
+        return false;
+
+    FreeCDR = ADAPTER_EIP202_MAX_PACKETS - FilledCDR;
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_FillLevel_Get \n");
+
+    if (EIP202_ContinuousScatter[InterfaceId])
+    {
+        return (FreeCDR >= GCount);
+    }
+    else
+    {
+        res = EIP202_RDR_FillLevel_Get(RDR_IOArea + InterfaceId,
+                                           &FilledRDR);
+        if (res != EIP202_RING_NO_ERROR)
+            return false;
+
+        if (FilledRDR > ADAPTER_EIP202_MAX_PACKETS)
+            return false;
+
+        FreeRDR = ADAPTER_EIP202_MAX_PACKETS - FilledRDR;
+
+        return (FreeCDR >= GCount && FreeRDR >= SCount);
+    }
+}
+#endif // ADAPTER_EIP202_ENABLE_SCATTERGATHER
+
+
+#ifdef ADAPTER_EIP202_INTERRUPTS_ENABLE
+/* Adapter_PECDev_IRQToInteraceID
+ */
+unsigned int
+Adapter_PECDev_IRQToInferfaceId(
+        const int nIRQ)
+{
+    unsigned int i, IRQ_Nr;
+
+    if (nIRQ < 0)
+        return 0;
+
+    IRQ_Nr = (unsigned int)nIRQ;
+
+    for (i = 0; i < ADAPTER_EIP202_DEVICE_COUNT; i++)
+    {
+        if (IRQ_Nr == EIP202_Devices[i].RDR_IRQ_ID ||
+            IRQ_Nr == EIP202_Devices[i].CDR_IRQ_ID)
+        {
+            return i;
+        }
+    }
+
+    LOG_CRIT("Adapter_PECDev_IRQToInterfaceId: unknown interrupt %d\n",nIRQ);
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Enable_ResultIRQ
+ */
+void
+Adapter_PECDev_Enable_ResultIRQ(
+        const unsigned int InterfaceId)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    LOG_INFO(
+      "\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable \n");
+
+    EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable (
+        RDR_IOArea + InterfaceId,
+        false);
+
+    LOG_INFO("\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_Enable \n");
+
+    EIP202_RDR_Processed_FillLevel_High_INT_Enable(
+        RDR_IOArea + InterfaceId,
+        ADAPTER_EIP202_DESCRIPTORDONECOUNT,
+        ADAPTER_EIP202_DESCRIPTORDONETIMEOUT,
+        true);
+
+    Adapter_Interrupt_Enable(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
+                             EIP202_Devices[InterfaceId].RDR_IRQ_Flags);
+
+    EIP202_Interrupts[InterfaceId] |= BIT_0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Disable_ResultIRQ
+ */
+void
+Adapter_PECDev_Disable_ResultIRQ(
+        const unsigned int InterfaceId)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    LOG_INFO(
+       "\n\t\t\t EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable \n");
+
+    EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable (
+        RDR_IOArea + InterfaceId,
+        false);
+
+    Adapter_Interrupt_Disable(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
+                              EIP202_Devices[InterfaceId].RDR_IRQ_Flags);
+
+    EIP202_Interrupts[InterfaceId] &= ~BIT_0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Enable_CommandIRQ
+ */
+void
+Adapter_PECDev_Enable_CommandIRQ(
+        const unsigned int InterfaceId)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Low_INT_Enable \n");
+
+    EIP202_CDR_FillLevel_Low_INT_Enable(
+        CDR_IOArea + InterfaceId,
+        ADAPTER_EIP202_DESCRIPTORDONECOUNT,
+        ADAPTER_EIP202_DESCRIPTORDONETIMEOUT);
+
+    Adapter_Interrupt_Enable(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
+                             EIP202_Devices[InterfaceId].CDR_IRQ_Flags);
+
+    EIP202_Interrupts[InterfaceId] |= BIT_1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Disable_CommandIRQ
+ */
+void
+Adapter_PECDev_Disable_CommandIRQ(
+        const unsigned int InterfaceId)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    LOG_INFO("\n\t\t\t EIP202_CDR_FillLevel_Low_INT_ClearAndDisable \n");
+
+    EIP202_CDR_FillLevel_Low_INT_ClearAndDisable(
+        CDR_IOArea + InterfaceId);
+
+    Adapter_Interrupt_Disable(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
+                              EIP202_Devices[InterfaceId].CDR_IRQ_Flags);
+
+    EIP202_Interrupts[InterfaceId] &= ~BIT_1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SetResultHandler
+ */
+void Adapter_PECDev_SetResultHandler(
+        const unsigned int InterfaceId,
+        Adapter_InterruptHandler_t HandlerFunction)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].RDR_IRQ_ID,
+                                 HandlerFunction);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_SetCommandHandler
+ */
+void Adapter_PECDev_SetCommandHandler(
+        const unsigned int InterfaceId,
+        Adapter_InterruptHandler_t HandlerFunction)
+{
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    Adapter_Interrupt_SetHandler(EIP202_Devices[InterfaceId].CDR_IRQ_ID,
+                                 HandlerFunction);
+}
+#endif // ADAPTER_EIP202_INTERRUPTS_ENABLE
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Scatter_Preload
+ */
+PEC_Status_t
+Adapter_PECDev_Scatter_Preload(
+        const unsigned int InterfaceId,
+        DMABuf_Handle_t * Handles_p,
+        const unsigned int HandlesCount)
+{
+    unsigned int i;
+    EIP202_RDR_Prepared_Control_t RDR_Control;
+    EIP202_Ring_Error_t res;
+    unsigned int Submitted,FilledRDR;
+    for (i = 0; i <  HandlesCount; i++)
+    {
+        DMABuf_Handle_t ParticleHandle = Handles_p[i];
+        DMAResource_Handle_t DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(ParticleHandle);
+        DMAResource_Record_t * Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+        RDR_Control.fFirstSegment           = true;
+#ifdef ADAPTER_EIP202_ENABLE_SCATTERGATHER
+        RDR_Control.fLastSegment            = false;
+#else
+        RDR_Control.fLastSegment            = true;
+        // When No scatter gather supported, packets must fit into single buffer.
+#endif
+        RDR_Control.PrepSegmentByteCount = Rec_p->Props.Size;
+        RDR_Control.ExpectedResultWordCount = 0;
+        EIP202_RDR_Prepared[InterfaceId][i].PrepControlWord =
+            EIP202_RDR_Write_Prepared_ControlWord(&RDR_Control);
+        Adapter_GetPhysAddr(ParticleHandle,
+                            &(EIP202_RDR_Prepared[InterfaceId][i].DstPacketAddr));
+    }
+    res = EIP202_RDR_Descriptor_Prepare(RDR_IOArea + InterfaceId,
+                                       EIP202_RDR_Prepared[InterfaceId],
+                                       HandlesCount,
+                                       &Submitted,
+                                       &FilledRDR);
+    if (res != EIP202_RING_NO_ERROR || Submitted != HandlesCount)
+    {
+        LOG_CRIT("Adapter_PECDev_Packet_Put: writing prepared descriptors"
+                 "error code %d count=%d expected=%d\n",
+                 res, Submitted, HandlesCount);
+        return PEC_ERROR_INTERNAL;
+    }
+
+    return PEC_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Put_Dump
+ */
+void
+Adapter_PECDev_Put_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpCDRAdmin,
+        const bool fDumpCDRCache)
+{
+    void * va;
+    unsigned int i, CDOffset;
+    uint32_t Word32;
+    EIP202_RingAdmin_t RingAdmin;
+    DMAResource_AddrPair_t Addr_Pair;
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    if (FirstSlotId >= ADAPTER_EIP202_MAX_PACKETS ||
+        LastSlotId >= ADAPTER_EIP202_MAX_PACKETS)
+        return;
+
+    if (FirstSlotId > LastSlotId)
+        return;
+
+    AdapterLib_Ring_EIP202_CDR_Status_Report(InterfaceId);
+
+    ZEROINIT(RingAdmin);
+    EIP202_CDR_Dump(CDR_IOArea + InterfaceId, &RingAdmin);
+    CDOffset = RingAdmin.DescOffsWordCount;
+
+    ZEROINIT(Addr_Pair);
+    DMAResource_Translate(CDR_Handle[InterfaceId],
+                          DMARES_DOMAIN_HOST,
+                          &Addr_Pair);
+    va = Addr_Pair.Address_p;
+
+    if (fDumpCDRAdmin)
+    {
+        void * pa;
+
+        ZEROINIT(Addr_Pair);
+        DMAResource_Translate(CDR_Handle[InterfaceId],
+                              DMARES_DOMAIN_BUS,
+                              &Addr_Pair);
+        pa = Addr_Pair.Address_p;
+
+        LOG_CRIT("\n\tCDR admin data, all sizes in 32-bit words:\n"
+                 "\tSeparate:         %s\n"
+                 "\tRing size:        %d\n"
+                 "\tDescriptor size:  %d\n"
+                 "\tInput ring size:  %d\n"
+                 "\tInput ring tail:  %d\n"
+                 "\tOutput ring size: %d\n"
+                 "\tOutput ring head: %d\n"
+                 "\tRing phys addr:   %p\n"
+                 "\tRing host addr:   %p\n",
+                 RingAdmin.fSeparate ? "yes" : "no",
+                 RingAdmin.RingSizeWordCount,
+                 RingAdmin.DescOffsWordCount,
+                 RingAdmin.IN_Size,
+                 RingAdmin.IN_Tail,
+                 RingAdmin.OUT_Size,
+                 RingAdmin.OUT_Head,
+                 pa,
+                 va);
+    }
+
+    LOG_CRIT("\n\tCDR dump, first slot %d, last slot %d\n",
+             FirstSlotId,
+             LastSlotId);
+
+    for (i = FirstSlotId; i <= LastSlotId; i++)
+    {
+        unsigned int j;
+
+        LOG_CRIT("\tDescriptor %d:\n", i);
+        for (j = 0; j < CDOffset; j++)
+        {
+            Word32 = DMAResource_Read32(CDR_Handle[InterfaceId],
+                                        i * CDOffset + j);
+
+            LOG_CRIT("\tCD[%02d] word[%02d] 0x%08x\n",
+                     i,
+                     j,
+                     Word32);
+        }
+    }
+
+    if (!fDumpCDRCache)
+        return;
+
+    LOG_CRIT("\n\tCDR cache dump, size %d entries\n",
+             ADAPTER_EIP202_MAX_LOGICDESCR);
+
+    for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
+    {
+        unsigned int j;
+
+        LOG_CRIT("\tDescriptor %d cache:\n", i);
+
+        Word32 = EIP202_CDR_Entries[InterfaceId][i].ControlWord;
+        LOG_CRIT("\tCDC[%02d] word[00] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_CDR_Entries[InterfaceId][i].SrcPacketAddr.Addr;
+        LOG_CRIT("\tCDC[%02d] word[02] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_CDR_Entries[InterfaceId][i].SrcPacketAddr.UpperAddr;
+        LOG_CRIT("\tCDC[%02d] word[03] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_CDR_Entries[InterfaceId][i].TokenDataAddr.Addr;
+        LOG_CRIT("\tCDC[%02d] word[04] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_CDR_Entries[InterfaceId][i].TokenDataAddr.UpperAddr;
+        LOG_CRIT("\tCDC[%02d] word[05] 0x%08x\n", i, Word32);
+
+        if (EIP202_CDR_Entries[InterfaceId][i].Token_p)
+            for (j = 0; j < IOToken_InWordCount_Get(); j++)
+            {
+                Word32 = EIP202_CDR_Entries[InterfaceId][i].Token_p[j];
+                LOG_CRIT("\tCDC[%02d] word[%02d] 0x%08x\n", i, 6 + j, Word32);
+            }
+    }
+
+    return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_PECDev_Get_Dump
+ */
+void
+Adapter_PECDev_Get_Dump(
+        const unsigned int InterfaceId,
+        const unsigned int FirstSlotId,
+        const unsigned int LastSlotId,
+        const bool fDumpRDRAdmin,
+        const bool fDumpRDRCache)
+{
+    void * va;
+    unsigned int i, RDOffset;
+    uint32_t Word32;
+    EIP202_RingAdmin_t RingAdmin;
+    DMAResource_AddrPair_t Addr_Pair;
+
+    if (InterfaceId >= ADAPTER_EIP202_DEVICE_COUNT)
+        return;
+
+    if (FirstSlotId >= ADAPTER_EIP202_MAX_PACKETS ||
+        LastSlotId >= ADAPTER_EIP202_MAX_PACKETS)
+        return;
+
+    if (FirstSlotId > LastSlotId)
+        return;
+
+    AdapterLib_Ring_EIP202_RDR_Status_Report(InterfaceId);
+
+    ZEROINIT(RingAdmin);
+    EIP202_RDR_Dump(RDR_IOArea + InterfaceId, &RingAdmin);
+    RDOffset = RingAdmin.DescOffsWordCount;
+
+    ZEROINIT(Addr_Pair);
+    DMAResource_Translate(RDR_Handle[InterfaceId],
+                          DMARES_DOMAIN_HOST,
+                          &Addr_Pair);
+    va = Addr_Pair.Address_p;
+
+    if (fDumpRDRAdmin)
+    {
+        void * pa;
+
+        ZEROINIT(Addr_Pair);
+        DMAResource_Translate(RDR_Handle[InterfaceId],
+                              DMARES_DOMAIN_BUS,
+                              &Addr_Pair);
+        pa = Addr_Pair.Address_p;
+
+        LOG_CRIT("\n\tRDR admin data, all sizes in 32-bit words:\n"
+                 "\tSeparate:         %s\n"
+                 "\tRing size:        %d\n"
+                 "\tDescriptor size:  %d\n"
+                 "\tInput ring size:  %d\n"
+                 "\tInput ring tail:  %d\n"
+                 "\tOutput ring size: %d\n"
+                 "\tOutput ring head: %d\n"
+                 "\tRing phys addr:   %p\n"
+                 "\tRing host addr:   %p\n",
+                 RingAdmin.fSeparate ? "yes" : "no",
+                 RingAdmin.RingSizeWordCount,
+                 RingAdmin.DescOffsWordCount,
+                 RingAdmin.IN_Size,
+                 RingAdmin.IN_Tail,
+                 RingAdmin.OUT_Size,
+                 RingAdmin.OUT_Head,
+                 pa,
+                 va);
+    }
+
+    LOG_CRIT("\n\tRDR dump, first slot %d, last slot %d\n",
+             FirstSlotId,
+             LastSlotId);
+
+    for (i = FirstSlotId; i <= LastSlotId; i++)
+    {
+        unsigned int j;
+
+        LOG_CRIT("\tDescriptor %d:\n", i);
+        for (j = 0; j < RDOffset; j++)
+        {
+            Word32 = DMAResource_Read32(RDR_Handle[InterfaceId],
+                                        i * RDOffset + j);
+
+            LOG_CRIT("\tRD[%02d] word[%02d] 0x%08x\n",
+                     i,
+                     j,
+                     Word32);
+        }
+    }
+
+    if (!fDumpRDRCache)
+        return;
+
+    LOG_CRIT("\n\tRDR cache dump, size %d entries\n",
+             ADAPTER_EIP202_MAX_LOGICDESCR);
+
+    for (i = 0; i < ADAPTER_EIP202_MAX_LOGICDESCR; i++)
+    {
+        unsigned int j;
+
+        LOG_CRIT("\tDescriptor %d cache:\n", i);
+
+        Word32 = EIP202_RDR_Entries[InterfaceId][i].ProcControlWord;
+        LOG_CRIT("\tRDC[%02d] word[00] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_RDR_Entries[InterfaceId][i].DstPacketAddr.Addr;
+        LOG_CRIT("\tRDC[%02d] word[02] 0x%08x\n", i, Word32);
+
+        Word32 = EIP202_RDR_Entries[InterfaceId][i].DstPacketAddr.UpperAddr;
+        LOG_CRIT("\tRDC[%02d] word[03] 0x%08x\n", i, Word32);
+
+        for (j = 0; j < IOToken_OutWordCount_Get(); j++)
+        {
+            Word32 = EIP202_RDR_Entries[InterfaceId][i].Token_p[j];
+            LOG_CRIT("\tRDC[%02d] word[%02d] 0x%08x\n", i, 4 + j, Word32);
+        }
+    }
+
+    return;
+}
+
+
+/* end of file adapter_ring_eip202.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_sglist.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_sglist.c
new file mode 100644
index 0000000..7ecf207
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/adapter_sglist.c
@@ -0,0 +1,385 @@
+/* adapter_sglist.c
+ *
+ * Packet Engine Control (PEC) Scatter Gather list API implementation.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "api_pec_sg.h"         // PEC_SG_* (the API we implement here)
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter PEC configuration
+#include "c_adapter_pec.h"
+
+// DMABuf API
+#include "api_dmabuf.h"         // DMABuf_*
+
+// Adapter DMABuf internal API
+#include "adapter_dmabuf.h"
+
+// Logging API
+#include "log.h"
+
+// Driver Framework DMAResource API
+#include "dmares_types.h"       // DMAResource_Handle_t
+#include "dmares_mgmt.h"        // DMAResource management functions
+#include "dmares_rw.h"          // DMAResource buffer access.
+#include "dmares_addr.h"        // DMAResource addr translation functions.
+#include "dmares_buf.h"         // DMAResource buffer allocations
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"               // memcpy, memset
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+
+// our internal definition of a scatter/gather list
+// the DMA buffer for SGList store this (variable-length) structure
+typedef struct
+{
+    unsigned int ListCapacity;
+
+    struct
+    {
+        DMABuf_Handle_t Handle;
+        unsigned int ByteCount;  // set by PEC_SGList_Write and PEC_Packet_Get
+    } Entries[1];       // variable-size allocated!!!
+
+} PEC_SGList_t;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Handle2SGList
+ *
+ * This function validates that the DMAResource handle is indeed an
+ * SGList handle
+ * and then returns the pointer to the PEC_SGList_t structure contained in
+ * the buffer related to this handle.
+ */
+static PEC_SGList_t *
+Adapter_Handle2SGListPtr(
+        DMABuf_Handle_t SGList_Handle)
+{
+    DMAResource_Handle_t * DMA_Handle =
+        Adapter_DMABuf_Handle2DMAResourceHandle(SGList_Handle);
+    DMAResource_Record_t * Rec_p;
+    if (DMAResource_IsValidHandle(DMA_Handle))
+        Rec_p = DMAResource_Handle2RecordPtr(DMA_Handle);
+    else
+        return NULL;
+
+    // ensure it is an SGList
+    if (Rec_p->sg.IsSGList != true)
+        return NULL;
+
+    return Adapter_DMAResource_HostAddr(
+        Adapter_DMABuf_Handle2DMAResourceHandle(SGList_Handle));
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_SGList_CalcAllocSize
+ *
+ * This function calculates the size of the buffer to be allocated to hold
+ * an PEC_SGList_t with a given capacity.
+ */
+static inline unsigned int
+Adapter_SGList_CalcAllocSize(
+        const unsigned int ListCapacity)
+{
+    PEC_SGList_t SG;
+    unsigned int S = sizeof(PEC_SGList_t);
+
+    S += (ListCapacity - 1) * sizeof(SG.Entries[1]);
+
+    return S;
+}
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Create
+ *
+ * This function must be used to create a list that can hold references to
+ * packet buffer fragments. The returned handle can be used in PEC_Packet_Put
+ * instead of a normal (contiguous) buffers.
+ *
+ * ListCapacity (input)
+ *     The number of scatter and/or gather fragments that this list can hold.
+ *
+ * SGList_Handle_p (output)
+ *     Pointer to the output parameter that will be filled in with the handle
+ *     that represents the newly created SGList.
+ */
+PEC_Status_t
+PEC_SGList_Create(
+        const unsigned int ListCapacity,
+        DMABuf_Handle_t * const SGList_Handle_p)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    DMAResource_AddrPair_t HostAddr;
+    int dmares;
+    DMAResource_Properties_t Props;
+
+    ZEROINIT(Props);
+
+    if (ListCapacity == 0 ||
+        SGList_Handle_p == NULL)
+    {
+        return PEC_ERROR_BAD_PARAMETER;
+    }
+
+    // initialize the output parameter
+    *SGList_Handle_p = DMABuf_NULLHandle;
+
+    Props.Size      = Adapter_SGList_CalcAllocSize(ListCapacity);
+    Props.Alignment = Adapter_DMAResource_Alignment_Get();
+
+    dmares = DMAResource_Alloc(Props, &HostAddr, &SGList_Handle_p->p);
+    if (dmares != 0)
+        return PEC_ERROR_INTERNAL;
+
+    // set the special flag in the DMA Resource record for SGLists
+    {
+        DMAResource_Handle_t DMAHandle;
+        DMAResource_Record_t * Rec_p;
+
+        DMAHandle = SGList_Handle_p->p;
+        Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+
+        if (!Rec_p)
+        {
+            // corner case - avoid memory leak
+            DMAResource_Release(Adapter_DMABuf_Handle2DMAResourceHandle(
+                                    *SGList_Handle_p));
+            *SGList_Handle_p = DMABuf_NULLHandle;
+
+            return PEC_ERROR_INTERNAL;
+        }
+
+        Rec_p->sg.IsSGList = true;
+    }
+
+    // initialize the SGList
+    {
+        PEC_SGList_t * const p = HostAddr.Address_p;
+        memset(p, 0, Props.Size);
+        p->ListCapacity = ListCapacity;
+    }
+
+    return PEC_STATUS_OK;
+#else
+    IDENTIFIER_NOT_USED(ListCapacity);
+    IDENTIFIER_NOT_USED(SGList_Handle_p);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Destroy
+ *
+ * This function must be used to destroy a SGList that was previously created
+ * with PEC_SGList_Create. The potentially referred fragments in the list are
+ * not freed by the implementation!
+ *
+ * SGList_Handle (input)
+ *     The handle to the SGList as returned by PEC_SGList_Create.
+ *
+ * DMABuf_Release may be called instead of this function.
+ */
+PEC_Status_t
+PEC_SGList_Destroy(
+        DMABuf_Handle_t SGList_Handle)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    int dmares;
+
+    dmares = DMAResource_Release(
+        Adapter_DMABuf_Handle2DMAResourceHandle(SGList_Handle));
+
+    if (dmares == 0)
+        return PEC_STATUS_OK;
+
+    return PEC_ERROR_BAD_HANDLE;
+#else
+    IDENTIFIER_NOT_USED(SGList_Handle.p);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Write
+ */
+PEC_Status_t
+PEC_SGList_Write(
+        DMABuf_Handle_t SGList_Handle,
+        const unsigned int Index,
+        DMABuf_Handle_t FragmentHandle,
+        const unsigned int FragmentByteCount)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_t * SGList_p;
+
+    SGList_p = Adapter_Handle2SGListPtr(SGList_Handle);
+    if (SGList_p == NULL)
+        return PEC_ERROR_BAD_HANDLE;
+
+    if (Index >= SGList_p->ListCapacity)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    SGList_p->Entries[Index].Handle = FragmentHandle;
+    SGList_p->Entries[Index].ByteCount = FragmentByteCount;
+
+    return PEC_STATUS_OK;
+#else
+    IDENTIFIER_NOT_USED(SGList_Handle.p);
+    IDENTIFIER_NOT_USED(Index);
+    IDENTIFIER_NOT_USED(FragmentHandle.p);
+    IDENTIFIER_NOT_USED(FragmentByteCount);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_Read
+ */
+PEC_Status_t
+PEC_SGList_Read(
+        DMABuf_Handle_t SGList_Handle,
+        const unsigned int Index,
+        DMABuf_Handle_t * const FragmentHandle_p,
+        unsigned int * const FragmentSizeInBytes_p,
+        uint8_t ** const FragmentPtr_p)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_t * SGList_p;
+
+    // initialize the output parameters
+    {
+        if (FragmentHandle_p)
+            *FragmentHandle_p = DMABuf_NULLHandle;
+
+        if (FragmentSizeInBytes_p)
+            *FragmentSizeInBytes_p = 0;
+
+        if (FragmentPtr_p)
+            *FragmentPtr_p = NULL;
+    }
+
+    SGList_p = Adapter_Handle2SGListPtr(SGList_Handle);
+    if (SGList_p == NULL)
+        return PEC_ERROR_BAD_HANDLE;
+
+    if (Index >= SGList_p->ListCapacity)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    // fill in the output parameters
+    {
+        if (FragmentHandle_p)
+            *FragmentHandle_p = SGList_p->Entries[Index].Handle;
+
+        if (FragmentSizeInBytes_p)
+            *FragmentSizeInBytes_p = SGList_p->Entries[Index].ByteCount;
+
+        if (FragmentPtr_p)
+        {
+            // retrieve the host address from the DMA resource record
+            DMAResource_Handle_t DMAHandle;
+            DMAResource_Record_t * Rec_p;
+
+            DMAHandle = Adapter_DMABuf_Handle2DMAResourceHandle(
+                SGList_p->Entries[Index].Handle);
+            Rec_p = DMAResource_Handle2RecordPtr(DMAHandle);
+            if (Rec_p)
+            {
+                // it is a valid handle
+                *FragmentPtr_p = Adapter_DMAResource_HostAddr(DMAHandle);
+            }
+        }
+    }
+
+    return PEC_STATUS_OK;
+#else
+    IDENTIFIER_NOT_USED(SGList_Handle.p);
+    IDENTIFIER_NOT_USED(Index);
+    IDENTIFIER_NOT_USED(FragmentHandle_p);
+    IDENTIFIER_NOT_USED(FragmentSizeInBytes_p);
+    IDENTIFIER_NOT_USED(FragmentPtr_p);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+}
+
+
+/*----------------------------------------------------------------------------
+ * PEC_SGList_GetCapacity
+ */
+PEC_Status_t
+PEC_SGList_GetCapacity(
+        DMABuf_Handle_t SGList_Handle,
+        unsigned int * const ListCapacity_p)
+{
+#ifdef ADAPTER_PEC_ENABLE_SCATTERGATHER
+    PEC_SGList_t * SGList_p;
+
+    if (ListCapacity_p == NULL)
+        return PEC_ERROR_BAD_PARAMETER;
+
+    // initialize the output parameter
+    *ListCapacity_p = 0;
+
+    SGList_p = Adapter_Handle2SGListPtr(SGList_Handle);
+    if (SGList_p != NULL)
+        *ListCapacity_p = SGList_p->ListCapacity;
+
+    return PEC_STATUS_OK;
+#else
+    IDENTIFIER_NOT_USED(SGList_Handle.p);
+    IDENTIFIER_NOT_USED(ListCapacity_p);
+
+    return PEC_ERROR_NOT_IMPLEMENTED;
+#endif /* ADAPTER_PEC_ENABLE_SCATTERGATHER */
+}
+
+
+
+/* end of file adapter_pec_sglist.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_firmware.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_firmware.c
new file mode 100644
index 0000000..4603741
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_firmware.c
@@ -0,0 +1,139 @@
+/* adapter_firmware.c
+ *
+ * Kernel-space implementation of Interface for obtaining the firmware image.
+ * Read from file system using Linux firmware API.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_firmware.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_adapter_firmware.h"
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+#include <linux/firmware.h>
+
+#include "adapter_alloc.h"
+
+// Logging API
+#include "log.h"
+
+#include "device_mgmt.h"  // Device_GetReference()
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_NULL
+ *
+ */
+const Adapter_Firmware_t Adapter_Firmware_NULL = NULL;
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_Acquire
+ */
+Adapter_Firmware_t
+Adapter_Firmware_Acquire(
+    const char * Firmware_Name_p,
+    const uint32_t ** Firmware_p,
+    unsigned int  * Firmware_Word32Count)
+{
+    uint32_t * Firmware_Data_p;
+    const struct firmware  *firmware;
+    int rc;
+    unsigned int i;
+
+    LOG_CRIT("Adapter_Firmware_Acquire for %s\n",Firmware_Name_p);
+
+    // Initialize output parameters.
+    *Firmware_p = NULL;
+    *Firmware_Word32Count = 0;
+
+    // Request firmware via kernel API.
+    rc = request_firmware(&firmware,
+                          Firmware_Name_p,
+                          Device_GetReference(NULL, NULL));
+    if (rc < 0)
+    {
+        LOG_CRIT("Adapter_Firmware_Acquire request of %s failed, rc=%d\n",
+                 Firmware_Name_p, rc);
+        return NULL;
+    }
+
+    if (firmware->data == NULL ||
+        firmware->size == 0 ||
+        firmware->size >= 256*1024 ||
+        firmware->size % sizeof(uint32_t) != 0)
+    {
+        LOG_CRIT("Adapter_Firmware_Acquire: Invalid image size %d\n",
+                 (int)firmware->size);
+        release_firmware(firmware);
+        return NULL;
+    }
+
+    // Allocate buffer for data
+    Firmware_Data_p = Adapter_Alloc(firmware->size);
+    if (Firmware_Data_p == NULL)
+    {
+        LOG_CRIT("Adapter_Firmware_Acquire: Failed to allocate\n");
+        release_firmware(firmware);
+        return NULL;
+    }
+
+    // Convert bytes from file to array of 32-bit words.
+    {
+        const uint8_t *p = firmware->data;
+        for (i=0; i<firmware->size / sizeof(uint32_t); i++)
+        {
+            Firmware_Data_p[i] = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
+            p += sizeof(uint32_t);
+        }
+    }
+
+    // Pass results to caller
+    *Firmware_p = Firmware_Data_p;
+    *Firmware_Word32Count = firmware->size / sizeof(uint32_t);
+
+    // Release firmware data structure.
+    release_firmware(firmware);
+
+    return (Adapter_Firmware_t)Firmware_Data_p;
+}
+
+/*----------------------------------------------------------------------------
+ * Adapter_Firmware_Release
+ */
+void
+Adapter_Firmware_Release(
+    Adapter_Firmware_t FirmwareHandle)
+{
+    LOG_CRIT("Adapter_Firmware_Release\n");
+    Adapter_Free((void*)FirmwareHandle);
+}
+
+
+
+/* end of file adapter_firmware.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_getpid.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_getpid.c
new file mode 100644
index 0000000..0465a50
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_getpid.c
@@ -0,0 +1,42 @@
+/* adapter_getpid.c
+ *
+ * Linux kernel specific Adapter module
+ * responsible for adapter-wide pid management.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2015-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// Adapter GetPid API
+#include "adapter_getpid.h"
+
+// Linux Kernel API
+#include <asm/current.h>       // process information
+#include <linux/sched.h>       // for "struct task_struct"
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_GetPid
+ */
+int
+Adapter_GetPid(void)
+{
+    return (int)current->pid;
+}
+
+
+/* end of file adapter_getpid.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_interrupts.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_interrupts.c
new file mode 100644
index 0000000..5d8779c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_interrupts.c
@@ -0,0 +1,830 @@
+/* adapter_interrupts.c
+ *
+ * Adapter EIP-202 module responsible for interrupts.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "adapter_interrupts.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default Adapter configuration
+#include "c_adapter_eip202.h"      // ADAPTER_*INTERRUPT*
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"            // bool, IDENTIFIER_NOT_USED
+
+// Driver Framework C-RunTime Library API
+#include "clib.h"                  // ZEROINIT
+
+// EIP-201 Advanced interrupt Controller (AIC)
+#include "eip201.h"
+
+// Logging API
+#include "log.h"
+
+// Driver Framework Device API
+#include "device_types.h"          // Device_Handle_t
+#include "device_mgmt.h"           // Device_Find, Device_GetReference
+
+// Linux Kernel API
+#include <linux/interrupt.h>       // request_irq, free_irq,
+                                   // DECLARE_TASKLET, tasklet_schedule,
+                                   // IRQ_DISABLED
+#include <linux/irq.h>             // IRQ_TYPE_LEVEL_HIGH
+#include <linux/irqreturn.h>       // irqreturn_t
+
+#ifdef ADAPTER_EIP202_USE_UMDEVXS_IRQ
+#include "umdevxs_interrupt.h"
+#endif
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define MAX_OS_IRQS                     256
+
+#define ARRAY_ELEMCOUNT(_a)             (sizeof(_a) / sizeof(_a[0]))
+
+#define ADAPTERINT_REQUEST_IRQ_FLAGS    (IRQF_SHARED)
+
+// Data structure for each Advanced interrupt controller
+typedef struct
+{
+    Device_Handle_t Device;
+    char *name;    // Device name (can be found with Device_Find().
+    int irq_idx;   // if isIRQ, then index of device interrupt.
+        // If !isIRQ. then driver IRQ number to which AIC is connected.
+    int irq;       // System IRQ number
+    int BitIRQs[32]; // Mapping from source bits to internal driver IRQ numbers.
+    bool isIRQ; // true if AIC has dedicated system IRQ line, false is it
+                // is cascaded from another AIC.
+} Adapter_AIC_t;
+
+// Data structure per interrupt
+typedef struct
+{
+    uint32_t SourceBitMask;
+    char * name;
+    Adapter_AIC_t *AIC;
+    char *AICName;
+    struct tasklet_struct tasklet;
+    Adapter_InterruptHandler_t Handler;
+    uint32_t Counter;
+    void *extra;
+    bool fHaveTasklet;
+    EIP201_Config_t Config;
+} Adapter_Interrupt_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static bool Adapter_IRQ_Initialized = false;
+
+#define ADAPTER_EIP202_ADD_AIC(_name,_idx, isirq)  \
+    {NULL, _name, _idx, -1, {0, }, isirq}
+
+
+static Adapter_AIC_t Adapter_AICTable[] = { ADAPTER_EIP202_AICS };
+
+#define ADAPTER_EIP202_ADD_IRQ(_name,_phy,_aicname,_tasklet,_pol)    \
+    {(1<<(_phy)),#_name,NULL,_aicname,{},NULL,0,NULL,_tasklet, \
+                                              EIP201_CONFIG_##_pol}
+
+static Adapter_Interrupt_t Adapter_IRQTable[] = { ADAPTER_EIP202_IRQS };
+
+// Define maximum number of supported interrupts
+#define ADAPTER_MAX_INTERRUPTS  ARRAY_ELEMCOUNT(Adapter_IRQTable)
+
+static Adapter_AIC_t * IRQ_AIC_Mapping[MAX_OS_IRQS];
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_GetActiveIntNr
+ *
+ * Returns 0..31 depending on the lowest '1' bit.
+ * Returns 32 when all bits are zero
+ *
+ * Using binary break-down algorithm.
+ */
+static inline int
+AdapterINT_GetActiveIntNr(
+        uint32_t Sources)
+{
+    unsigned int IntNr = 0;
+    unsigned int R16, R8, R4, R2;
+
+    if (Sources == 0)
+        return 32;
+
+    // if the lower 16 bits are empty, look at the upper 16 bits
+    R16 = Sources & 0xFFFF;
+    if (R16 == 0)
+    {
+        IntNr += 16;
+        R16 = Sources >> 16;
+    }
+
+    // if the lower 8 bits are empty, look at the high 8 bits
+    R8 = R16 & 0xFF;
+    if (R8 == 0)
+    {
+        IntNr += 8;
+        R8 = R16 >> 8;
+    }
+    R4 = R8 & 0xF;
+    if (R4 == 0)
+    {
+        IntNr += 4;
+        R4 = R8 >> 4;
+    }
+
+    R2 = R4 & 3;
+    if (R2 == 0)
+    {
+        IntNr += 2;
+        R2 = R4 >> 2;
+    }
+
+    // last two bits are trivial
+    // 00 => cannot happen
+    // 01 => +0
+    // 10 => +1
+    // 11 => +0
+    if (R2 == 2)
+        IntNr++;
+
+    return IntNr;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_Report_InterruptCounters
+ */
+static void
+AdapterINT_Report_InterruptCounters(void)
+{
+    int i;
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_IRQTable); i++)
+    {
+        if ( (1<<i) & ADAPTER_EIP202_INTERRUPTS_TRACEFILTER)
+        {
+            LOG_CRIT("AIC %s interrupt source %s mask %08x counter %d\n",
+                     Adapter_IRQTable[i].AICName,
+                     Adapter_IRQTable[i].name,
+                     Adapter_IRQTable[i].SourceBitMask,
+                     Adapter_IRQTable[i].Counter);
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_Enable
+ */
+int
+Adapter_Interrupt_Enable(
+        const int nIRQ,
+        const unsigned int Flags)
+{
+    int rc = -1;
+    IDENTIFIER_NOT_USED(Flags);
+
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+    if (nIRQ < 0 || nIRQ >= ADAPTER_MAX_INTERRUPTS)
+    {
+            LOG_CRIT(
+                    "Adapter_Interrupt_Enable: "
+                    "Failed, IRQ %d not supported\n",
+                    nIRQ);
+    }
+    else
+    {
+        rc=EIP201_SourceMask_EnableSource(Adapter_IRQTable[nIRQ].AIC->Device,
+                                       Adapter_IRQTable[nIRQ].SourceBitMask);
+        LOG_INFO("\n\t\t\tAdapter_Interrupt_Enable "
+                 "IRQ %d %s %s mask=%08x\n",
+                 nIRQ,
+                 Adapter_IRQTable[nIRQ].AICName,
+                 Adapter_IRQTable[nIRQ].name,
+                 Adapter_IRQTable[nIRQ].SourceBitMask);
+   }
+
+    LOG_INFO("\n\t\t %s done \n", __func__);
+    return rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_Disable
+ */
+int
+Adapter_Interrupt_Disable(
+        const int nIRQ,
+        const unsigned int Flags)
+{
+    int rc = -1;
+    IDENTIFIER_NOT_USED(Flags);
+
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+    if (nIRQ < 0 || nIRQ >= ADAPTER_MAX_INTERRUPTS)
+    {
+            LOG_CRIT(
+                    "Adapter_Interrupt_Disable: "
+                    "Failed, IRQ %d not supported\n",
+                    nIRQ);
+    }
+    else
+    {
+        rc = EIP201_SourceMask_DisableSource(Adapter_IRQTable[nIRQ].AIC->Device,
+                                       Adapter_IRQTable[nIRQ].SourceBitMask);
+        LOG_INFO("\n\t\t\tAdapter_Interrupt_Disable "
+                 "IRQ %d %s %s mask=%08x\n",
+                 nIRQ,
+                 Adapter_IRQTable[nIRQ].AICName,
+                 Adapter_IRQTable[nIRQ].name,
+                 Adapter_IRQTable[nIRQ].SourceBitMask);
+    }
+
+    LOG_INFO("\n\t\t %s done \n", __func__);
+    return rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupt_SetHandler
+ */
+int
+Adapter_Interrupt_SetHandler(
+        const int nIRQ,
+        Adapter_InterruptHandler_t HandlerFunction)
+{
+    if (nIRQ < 0 || nIRQ >= ADAPTER_MAX_INTERRUPTS)
+        return -1;
+
+    LOG_INFO(
+            "Adapter_Interrupt_SetHandler: "
+            "HandlerFnc=%p for IRQ %d\n",
+            HandlerFunction,
+            nIRQ);
+
+    Adapter_IRQTable[nIRQ].Handler = HandlerFunction;
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_CommonTasklet
+ *
+ * This handler is scheduled in the top-halve interrupt handler when it
+ * decodes one of the CDR or RDR interrupt sources.
+ * The data parameter is the IRQ value (from adapter_interrupts.h) for that
+ * specific interrupt source.
+ */
+static void
+AdapterINT_CommonTasklet(
+        unsigned long data)
+{
+    const unsigned int IntNr = (unsigned int)data;
+    Adapter_InterruptHandler_t H;
+
+    LOG_INFO("\n\t\t%s \n", __func__);
+
+    LOG_INFO("Tasklet invoked intnr=%d\n",IntNr);
+
+    // verify we have a handler
+    H = Adapter_IRQTable[IntNr].Handler;
+
+    if (H)
+    {
+        // invoke the handler
+        H(IntNr, 0);
+    }
+    else
+    {
+        LOG_CRIT(
+            "AdapterINT_CommonTasklet: "
+            "Error, disabling IRQ %d with missing handler\n",
+            IntNr);
+
+        Adapter_Interrupt_Disable(IntNr, 0);
+    }
+
+    LOG_INFO("\n\t\t%s done\n", __func__);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_AICHandler
+ *
+ * Handle all interrupts connected to the specified AIC.
+ *
+ * If this AIC is connected directly to a system IRQ line, this is
+ * called directly from the Top Half Handler.
+ *
+ * If this AIC is connected via an IRQ line of another AIC, this is
+ * called from the handler function of that interrupt.
+ *
+ * Return: 0 for success, -1 for failure.
+ */
+static int
+AdapterINT_AICHandler(Adapter_AIC_t *AIC)
+{
+    EIP201_SourceBitmap_t Sources;
+    int IntNr, irq, rc = 0;
+
+    LOG_INFO("\n\t\t%s \n", __func__);
+
+    if (AIC == NULL)
+        return -1;
+
+    if (AIC->Device == NULL)
+    {
+        LOG_INFO("%s: skipping spurious interrupt for AIC %s, IRQ %d\n",
+                 __func__,
+                 AIC->name,
+                 AIC->irq);
+        goto exit; // no error
+    }
+
+    Sources = EIP201_SourceStatus_ReadAllEnabled(AIC->Device);
+    if (Sources == 0)
+    {
+        rc = -1;
+        goto exit; // error
+    }
+
+    EIP201_Acknowledge(AIC->Device, Sources);
+
+    LOG_INFO("%s: AIC %s, IRQ %d, sources=%x\n",
+             __func__,
+             AIC->name,
+             AIC->irq,
+             Sources);
+
+    while (Sources)
+    {
+        IntNr = AdapterINT_GetActiveIntNr(Sources);
+
+        /* Get number of first bit set */
+        Sources &= ~(1<<IntNr);
+
+        /* Clear this in sources */
+        irq = AIC->BitIRQs[IntNr];
+
+        LOG_INFO("%s: Handle IRQ %d for AIC %s\n", __func__, irq, AIC->name);
+
+        if (irq < 0 || irq >= ADAPTER_MAX_INTERRUPTS)
+        {
+            LOG_CRIT("%s: %s IRQ not defined for bit %d, disabling source\n",
+                     __func__,
+                     AIC->name,
+                     IntNr);
+            EIP201_SourceMask_DisableSource(AIC->Device, (1<<IntNr));
+        }
+
+        Adapter_IRQTable[irq].Counter++;
+
+        if ( (1<<irq) & ADAPTER_EIP202_INTERRUPTS_TRACEFILTER)
+            LOG_CRIT("%s: encountered interrupt %d, bit %d for AIC %s\n",
+                     __func__,
+                     irq,
+                     IntNr,
+                     AIC->name);
+
+        if(Adapter_IRQTable[irq].fHaveTasklet)
+        {
+            LOG_INFO("%s: Start tasklet\n", __func__);
+            /* IRQ is handled via tasklet */
+            tasklet_schedule(&Adapter_IRQTable[irq].tasklet);
+            Adapter_Interrupt_Disable(irq, 0);
+        }
+        else
+        {
+            Adapter_InterruptHandler_t H = Adapter_IRQTable[irq].Handler;
+            LOG_INFO("%s: Run normal handler\n", __func__);
+            /* Handler is called directly */
+            if (H)
+            {
+                H(irq, 0);
+            }
+            else
+            {
+                LOG_CRIT(
+                    "%s : Error, disabling IRQ %d with missing handler\n",
+                    __func__,
+                    irq);
+
+                Adapter_Interrupt_Disable(irq, 0);
+            }
+        }
+    } // while
+
+exit:
+    LOG_INFO("\n\t\t%s done\n", __func__);
+    return rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_TopHalfHandler
+ *
+ * This is the interrupt handler function call by the kernel when our hooked
+ * interrupt is active.
+ *
+ * Call the handler for the associated AIC.
+ */
+static irqreturn_t
+AdapterINT_TopHalfHandler(
+        int irq,
+        void * dev_id)
+{
+    irqreturn_t Int_Rc = IRQ_NONE;
+    LOG_INFO("\n\t\t%s \n", __func__);
+
+    if (irq < 0 || irq >= MAX_OS_IRQS || IRQ_AIC_Mapping[irq]==NULL)
+    {
+        LOG_CRIT("%s: No AIC defined for IRQ %d\n",__func__,irq);
+        goto error;
+    }
+
+    if ( AdapterINT_AICHandler(IRQ_AIC_Mapping[irq]) < 0)
+    {
+        goto error;
+    }
+
+    Int_Rc = IRQ_HANDLED;
+
+error:
+    LOG_INFO("\n\t\t%s done\n", __func__);
+
+    IDENTIFIER_NOT_USED(dev_id);
+    return Int_Rc;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_ChainedAIC
+ *
+ * Handler function for IRQ that services an entire AIC.
+ */
+static void
+AdapterINT_ChainedAIC(const int irq, const unsigned int flags)
+{
+    IDENTIFIER_NOT_USED(flags);
+    AdapterINT_AICHandler(Adapter_IRQTable[irq].extra);
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_SetInternalLinkage
+ *
+ * Create AIC References in Adapter_IRQTable.
+ * Fill in BitIRQs references in Adapter_AICTable.
+ * Perform some consistency checks.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+static int
+AdapterINT_SetInternalLinkage(void)
+{
+    int i,j;
+    int IntNr;
+
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_IRQTable); i++)
+    {
+        Adapter_IRQTable[i].AIC = NULL;
+    }
+
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_AICTable); i++)
+    {
+        for (j=0; j<32; j++)
+        {
+            Adapter_AICTable[i].BitIRQs[j] = -1;
+        }
+        for (j=0; j<ARRAY_ELEMCOUNT(Adapter_IRQTable); j++)
+        {
+            if (strcmp(Adapter_AICTable[i].name, Adapter_IRQTable[j].AICName)
+                == 0)
+            {
+                if (Adapter_IRQTable[j].AIC)
+                {
+                    LOG_CRIT("%s: AIC link set more than once\n",__func__);
+                }
+                Adapter_IRQTable[j].AIC = Adapter_AICTable + i;
+                IntNr = AdapterINT_GetActiveIntNr(
+                    Adapter_IRQTable[j].SourceBitMask);
+                if (IntNr < 0 || IntNr >= 32)
+                {
+                    LOG_CRIT("%s: IRQ %d source bit %d out of range\n",
+                             __func__,j,IntNr);
+                    return -1;
+                }
+                else if (Adapter_AICTable[i].BitIRQs[IntNr] >= 0)
+                {
+                    LOG_CRIT(
+                        "%s: AIC %s IRQ %d source bit %d already defined\n",
+                        __func__,
+                        Adapter_AICTable[i].name,
+                        j,
+                        IntNr);
+                    return -1;
+                }
+                else
+                {
+                    Adapter_AICTable[i].BitIRQs[IntNr] = j;
+                }
+            }
+        }
+    }
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_IRQTable); i++)
+    {
+        if (Adapter_IRQTable[i].AIC == NULL)
+        {
+            LOG_CRIT("%s: AIC pointer of IRQ %d is null\n",__func__,i);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_AIC_Init
+ *
+ */
+static bool
+AdapterINT_AIC_Init(void)
+{
+    EIP201_Status_t res;
+    unsigned int i;
+
+    // Initialize all configured EIP-201 AIC devices
+    for (i = 0; i < ARRAY_ELEMCOUNT(Adapter_AICTable); i++)
+    {
+        LOG_INFO("%s: Initialize AIC %s\n",__func__,Adapter_AICTable[i].name);
+
+        Adapter_AICTable[i].Device = Device_Find(Adapter_AICTable[i].name);
+        if (Adapter_AICTable[i].Device == NULL)
+        {
+            LOG_CRIT("%s: Device_Find() failed for %s\n",
+                     __func__,
+                     Adapter_AICTable[i].name);
+            return false; // error
+        }
+
+        res = EIP201_Initialize(Adapter_AICTable[i].Device, NULL, 0);
+        if (res != EIP201_STATUS_SUCCESS)
+        {
+            LOG_CRIT("%s: EIP201_Initialize() failed, error %d\n", __func__, res);
+            return false; // error
+        }
+    }
+
+    return true; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * AdapterINT_AIC_Enable
+ *
+ */
+static void
+AdapterINT_AIC_Enable(void)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_ELEMCOUNT(Adapter_AICTable); i++)
+        if (!Adapter_AICTable[i].isIRQ)
+            Adapter_Interrupt_Enable(Adapter_AICTable[i].irq_idx, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_Init
+ *
+ */
+int
+Adapter_Interrupts_Init(
+        const int nIRQ)
+{
+    int i;
+    int IntNr = nIRQ;
+
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+    if (AdapterINT_SetInternalLinkage() < 0)
+    {
+        LOG_CRIT("Interrupt AIC and IRQ tables are inconsistent\n");
+        return -1;
+    }
+
+    // Initialize the AIC devices
+    if (!AdapterINT_AIC_Init())
+        return -1;
+
+    // Initialize the Adapter_IRQTable and tasklets.
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_IRQTable); i++)
+    {
+        Adapter_IRQTable[i].Handler = NULL;
+        Adapter_IRQTable[i].extra = NULL;
+        Adapter_IRQTable[i].Counter = 0;
+        if (Adapter_IRQTable[i].fHaveTasklet)
+            tasklet_init(&Adapter_IRQTable[i].tasklet,
+                         AdapterINT_CommonTasklet,
+                         (long)i);
+        EIP201_Config_Change(Adapter_IRQTable[i].AIC->Device,
+                             Adapter_IRQTable[i].SourceBitMask,
+                             Adapter_IRQTable[i].Config);
+        // Clear any pending egde-sensitive interrupts.
+        EIP201_Acknowledge(Adapter_IRQTable[i].AIC->Device,
+                           Adapter_IRQTable[i].SourceBitMask);
+    }
+
+    // Request the IRQs for each AIC or register to IRQ of other AIC.
+    for (i=0; i<ARRAY_ELEMCOUNT(Adapter_AICTable); i++)
+    {
+        if (Adapter_AICTable[i].isIRQ)
+        {
+            int res;
+
+            LOG_INFO("\n\t\t %s: Request IRQ for AIC %s\n",
+                     __func__,Adapter_AICTable[i].name);
+
+#ifdef ADAPTER_EIP202_USE_UMDEVXS_IRQ
+            res = UMDevXS_Interrupt_Request(AdapterINT_TopHalfHandler,
+                                            Adapter_AICTable[i].irq_idx);
+            IntNr = res;
+#else
+            {
+                struct device * Device_p;
+                // Get device reference for this resource
+                Device_p = Device_GetReference(NULL, NULL);
+                res = request_irq(IntNr,
+                                  AdapterINT_TopHalfHandler,
+                                  ADAPTERINT_REQUEST_IRQ_FLAGS,
+                                  ADAPTER_EIP202_DRIVER_NAME,
+                                  Device_p);
+            }
+#endif
+            if (res < 0)
+            {
+                LOG_CRIT("%s: Request IRQ error %d\n", __func__, res);
+                return res;
+            }
+            else
+            {
+                Adapter_AICTable[i].irq = IntNr;
+                IRQ_AIC_Mapping[IntNr] = Adapter_AICTable + i;
+                LOG_INFO("%s: Successfully hooked IRQ %d\n", __func__, IntNr);
+            }
+        }
+        else
+        {
+            IntNr = Adapter_AICTable[i].irq_idx;
+            LOG_INFO("%s: Hook up AIC %s to chained IRQ %d\n",
+                     __func__,
+                     Adapter_AICTable[i].name,
+                     IntNr);
+            if (IntNr < 0 || IntNr >= ADAPTER_MAX_INTERRUPTS)
+            {
+                LOG_CRIT("%s: IRQ %d out of range\n", __func__,IntNr);
+            }
+            Adapter_IRQTable[IntNr].extra =  Adapter_AICTable + i;
+            Adapter_Interrupt_SetHandler(IntNr, AdapterINT_ChainedAIC);
+        }
+    }
+
+    // Enable AIC
+    AdapterINT_AIC_Enable();
+
+    LOG_INFO("\n\t\t %s done\n", __func__);
+    Adapter_IRQ_Initialized = true;
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_UnInit
+ */
+int
+Adapter_Interrupts_UnInit(const int nIRQ)
+{
+    unsigned int i;
+    IDENTIFIER_NOT_USED(nIRQ);
+
+    LOG_INFO("\n\t\t %s \n", __func__);
+    if (!Adapter_IRQ_Initialized)
+        return -1;
+
+    // disable all interrupts
+    for (i = 0; i < ARRAY_ELEMCOUNT(Adapter_AICTable); i++)
+    {
+        if (Adapter_AICTable[i].Device)
+        {
+            EIP201_SourceMask_DisableSource(Adapter_AICTable[i].Device,
+                                            EIP201_SOURCE_ALL);
+            Adapter_AICTable[i].Device = NULL;
+        }
+
+        if(Adapter_AICTable[i].isIRQ && Adapter_AICTable[i].irq > 0)
+        {
+#ifdef ADAPTER_EIP202_USE_UMDEVXS_IRQ
+            UMDevXS_Interrupt_Request(NULL,Adapter_AICTable[i].irq_idx);
+#else
+            // Get device reference for this resource
+            struct device * Device_p = Device_GetReference(NULL, NULL);
+
+            LOG_INFO("%s: Free IRQ %d for AIC %s\n",
+                     __func__,
+                     Adapter_AICTable[i].irq,
+                     Adapter_AICTable[i].name);
+
+            // unhook the interrupt
+            free_irq(Adapter_AICTable[i].irq, Device_p);
+
+            LOG_INFO("%s: Successfully freed IRQ %d for AIC %s\n",
+                     __func__,
+                     Adapter_AICTable[i].irq,
+                     Adapter_AICTable[i].name);
+#endif
+        }
+    }
+
+    // Kill all tasklets
+    for (i = 0; i < ARRAY_ELEMCOUNT(Adapter_IRQTable); i++)
+        if (Adapter_IRQTable[i].fHaveTasklet)
+            tasklet_kill(&Adapter_IRQTable[i].tasklet);
+
+    AdapterINT_Report_InterruptCounters();
+
+    ZEROINIT(IRQ_AIC_Mapping);
+
+    Adapter_IRQ_Initialized = false;
+
+    LOG_INFO("\n\t\t %s done\n", __func__);
+
+    return 0;
+}
+
+
+#ifdef ADAPTER_PEC_RPM_EIP202_DEVICE0_ID
+/*----------------------------------------------------------------------------
+ * Adapter_Interrupts_Resume
+ */
+int
+Adapter_Interrupts_Resume(void)
+{
+    LOG_INFO("\n\t\t %s \n", __func__);
+
+    if (!Adapter_IRQ_Initialized)
+    {
+        LOG_CRIT("%s: failed, not initialized\n", __func__);
+        return -1;
+    }
+
+    // Resume AIC devices
+    if (!AdapterINT_AIC_Init())
+        return -2; // error
+
+    // Re-enable AIC interrupts
+    AdapterINT_AIC_Enable();
+
+    LOG_INFO("\n\t\t %s done\n", __func__);
+
+    return 0; // success
+}
+#endif
+
+
+/* end of file adapter_interrupts.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_lock.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_lock.c
new file mode 100644
index 0000000..38b663f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_lock.c
@@ -0,0 +1,118 @@
+/* adapter_lock.c
+ *
+ * Adapter concurrency (locking) management
+ * Linux kernel-space implementation
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Adapter locking API
+#include "adapter_lock.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"         // IDENTIFIER_NOT_USED
+
+// Adapter Lock Internal API
+#include "adapter_lock_internal.h"
+
+// Adapter Memory Allocation API
+#include "adapter_alloc.h"
+
+// Logging API
+#undef LOG_SEVERITY_MAX
+#define LOG_SEVERITY_MAX    LOG_SEVERITY_WARN
+#include "log.h"
+
+// Linux Kernel API
+#include <linux/spinlock.h>     // spinlock_*
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Alloc
+ */
+Adapter_Lock_t
+Adapter_Lock_Alloc(void)
+{
+    spinlock_t * Lock_p;
+
+    size_t LockSize=sizeof(spinlock_t);
+    if (LockSize==0)
+        LockSize=4;
+
+    Lock_p = Adapter_Alloc(LockSize);
+    if (Lock_p == NULL)
+        return Adapter_Lock_NULL;
+
+    Log_FormattedMessage("%s: Lock = spinlock\n", __func__);
+
+    spin_lock_init(Lock_p);
+
+    return Lock_p;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Free
+ */
+void
+Adapter_Lock_Free(Adapter_Lock_t Lock)
+{
+    Adapter_Free((void*)Lock);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Acquire
+ */
+void
+Adapter_Lock_Acquire(
+        Adapter_Lock_t Lock,
+        unsigned long * Flags)
+{
+    spin_lock_irqsave((spinlock_t *)Lock, *Flags);
+}
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_Lock_Release
+ */
+void
+Adapter_Lock_Release(
+        Adapter_Lock_t Lock,
+        unsigned long * Flags)
+{
+    spin_unlock_irqrestore((spinlock_t *)Lock, *Flags);
+}
+
+
+/* end of file adapter_lock.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_sleep.c b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_sleep.c
new file mode 100644
index 0000000..88e4be0
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/slad/lkm/adapter_sleep.c
@@ -0,0 +1,45 @@
+/* adapter_sleep.c
+ *
+ * Linux kernel specific Adapter module
+ * responsible for adapter-wide time management.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// Adapter Sleep API
+#include "adapter_sleep.h"
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h"
+
+// Linux Kernel API
+#include <linux/delay.h>        // msleep, no-busy-waiting implementation
+
+
+/*----------------------------------------------------------------------------
+ * Adapter_SleepMS
+ */
+void
+Adapter_SleepMS(
+        const unsigned int Duration_ms)
+{
+    msleep(Duration_ms);
+}
+
+
+/* end of file adapter_sleep.c */