[][openwrt][mt7988][crypto][EIP197 Alpha Release]
[Description]
Add alpha version of EIP197 package(crypto-eip)
[Release-log]
N/A
Change-Id: Ib90915f531aa238b90bd0fecc81e2ec3bf6016cc
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7908928
diff --git a/package-21.02/kernel/crypto-eip/Config.in b/package-21.02/kernel/crypto-eip/Config.in
new file mode 100644
index 0000000..c68eb36
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/Config.in
@@ -0,0 +1,30 @@
+menu "Crypto Offload Configuration"
+ depends on PACKAGE_kmod-crypto-eip
+
+choice
+ prompt "Crypto Offload Mode"
+ default CRYPTO_OFFLOAD_INLINE
+ help
+ Select crypto offload mode. Support lookaside mode or inline mode.
+
+config CRYPTO_OFFLOAD_INLINE
+ bool "Inline Mode"
+ depends on TARGET_mediatek_mt7988 && !PACKAGE_kmod-eip197_driver
+ select PACKAGE_kmod-crypto-eip-inline
+ select PACKAGE_kmod-crypto-eip-ddk
+ select PACKAGE_crypto-eip-inline-fw
+endchoice
+
+choice
+ prompt "Crypto XFRM Offload Method"
+ depends on CRYPTO_OFFLOAD_INLINE
+ default CRYPTO_XFRM_OFFLOAD_MTK_PCE
+ help
+ Select crypto XFRM offload method. Either RAMBUS PCL support or
+ MTK PCE support.
+
+config CRYPTO_XFRM_OFFLOAD_MTK_PCE
+ bool "Enable MTK PCE XFRM Offload"
+endchoice
+
+endmenu
diff --git a/package-21.02/kernel/crypto-eip/Makefile b/package-21.02/kernel/crypto-eip/Makefile
new file mode 100644
index 0000000..494eadb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/Makefile
@@ -0,0 +1,46 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=crypto-eip
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/package-defaults.mk
+
+# For package initialization such as menuconfig or description etc.
+EIP_KERNEL_PKGS:=
+EIP_PKGS:=
+
+include crypto-eip.mk
+include $(filter-out crypto-eip.mk,$(wildcard *.mk))
+
+EXTRA_CFLAGS+= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG))))
+
+EXTRA_CFLAGS+= -Wall -Werror
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)/firmware
+ $(CP) -r `find ./firmware -maxdepth 1 | grep -v ".git"` $(PKG_BUILD_DIR)/firmware/
+ $(CP) -r `find ./src -maxdepth 1 | grep -v ".git"` $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(KERNEL_MAKE_FLAGS) \
+ M="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG) \
+ modules
+endef
+
+$(foreach KERNEL_PKG,$(EIP_KERNEL_PKGS),$(eval $(call KernelPackage,$(KERNEL_PKG))))
+$(foreach PKG,$(EIP_PKGS),$(eval $(call BuildPackage,$(PKG))))
diff --git a/package-21.02/kernel/crypto-eip/crypto-eip-ddk.mk b/package-21.02/kernel/crypto-eip/crypto-eip-ddk.mk
new file mode 100644
index 0000000..bd6f30a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/crypto-eip-ddk.mk
@@ -0,0 +1,55 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+# Configure for crypto-eip DDK makefile
+EIP_KERNEL_PKGS+= \
+ crypto-eip-ddk
+
+ifeq ($(CONFIG_PACKAGE_kmod-crypto-eip-ddk),y)
+EXTRA_KCONFIG+= \
+ CONFIG_RAMBUS_DDK=m
+
+EXTRA_CFLAGS+= \
+ -I$(PKG_BUILD_DIR)/ddk/inc \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/configs \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/device \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/device/lkm \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/device/lkm/of \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/dmares \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/firmware_api \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/builder/sa \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/builder/token \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/eip197 \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/iotoken \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/list \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/kit/ring \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/libc \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/log \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/shdevxs \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/slad \
+ -I$(PKG_BUILD_DIR)/ddk/inc/crypto-eip/ddk/slad/lkm \
+ -DEIP197_BUS_VERSION_AXI3 \
+ -DDRIVER_64BIT_HOST \
+ -DDRIVER_64BIT_DEVICE \
+ -DADAPTER_AUTO_TOKENBUILDER
+endif
+
+# crypto-eip-ddk kernel package configuration
+define KernelPackage/crypto-eip-ddk
+ CATEGORY:=MTK Properties
+ SUBMENU:=Drivers
+ TITLE:= MTK EIP DDK
+ FILES+=$(PKG_BUILD_DIR)/ddk/crypto-eip-ddk.ko
+ DEPENDS:= \
+ @CRYPTO_OFFLOAD_INLINE \
+ kmod-crypto-eip
+endef
+
+define KernelPackage/crypto-eip-ddk/description
+ Porting DDK source code to package.
+endef
diff --git a/package-21.02/kernel/crypto-eip/crypto-eip-fw.mk b/package-21.02/kernel/crypto-eip/crypto-eip-fw.mk
new file mode 100644
index 0000000..eabefae
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/crypto-eip-fw.mk
@@ -0,0 +1,31 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+# Configure for crypto firmware makefile
+EIP_PKGS+= \
+ crypto-eip-inline-fw
+
+define Package/crypto-eip-inline-fw
+ TITLE:=Mediatek EIP Firmware
+ SECTION:=firmware
+ CATEGORY:=Firmware
+ DEPENDS:=@CRYPTO_OFFLOAD_INLINE
+endef
+
+define Package/crypto-eip-inline-fw/description
+ Load firmware for EIP197 inline mode.
+endef
+
+define Package/crypto-eip-inline-fw/install
+ $(INSTALL_DIR) $(1)/lib/firmware/
+ $(CP) \
+ $(PKG_BUILD_DIR)/firmware/bin/firmware_eip207_ifpp.bin \
+ $(PKG_BUILD_DIR)/firmware/bin/firmware_eip207_ipue.bin \
+ $(PKG_BUILD_DIR)/firmware/bin/firmware_eip207_ofpp.bin \
+ $(PKG_BUILD_DIR)/firmware/bin/firmware_eip207_opue.bin \
+ $(1)/lib/firmware/
+endef
diff --git a/package-21.02/kernel/crypto-eip/crypto-eip.mk b/package-21.02/kernel/crypto-eip/crypto-eip.mk
new file mode 100644
index 0000000..31df9bd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/crypto-eip.mk
@@ -0,0 +1,82 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+# Configure for crypto-eip top makefile
+EIP_KERNEL_PKGS+= \
+ crypto-eip \
+ crypto-eip-inline
+
+ifeq ($(CONFIG_PACKAGE_kmod-crypto-eip),y)
+EXTRA_KCONFIG+= \
+ CONFIG_CRYPTO_OFFLOAD_INLINE=$(CONFIG_CRYPTO_OFFLOAD_INLINE)
+endif
+
+ifeq ($(CONFIG_CRYPTO_OFFLOAD_INLINE),y)
+EXTRA_KCONFIG+= \
+ CONFIG_MTK_CRYPTO_EIP_INLINE=m \
+ CONFIG_CRYPTO_XFRM_OFFLOAD_MTK_PCE=$(CONFIG_CRYPTO_XFRM_OFFLOAD_MTK_PCE)
+
+EXTRA_CFLAGS+= \
+ -I$(LINUX_DIR)/drivers/net/ethernet/mediatek/ \
+ -I$(KERNEL_BUILD_DIR)/pce/inc/
+endif
+
+# crypto-eip kernel package configuration
+define KernelPackage/crypto-eip
+ CATEGORY:=MTK Properties
+ SUBMENU:=Drivers
+ TITLE:= EIP-197 Crypto Engine Driver
+ DEFAULT:=y
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_AUTHENC=y \
+ CONFIG_CRYPTO_AES=y \
+ CONFIG_CRYPTO_AEAD=y \
+ CONFIG_CRYPTO_DES=y \
+ CONFIG_CRYPTO_MD5=y \
+ CONFIG_CRYPTO_SHA1=y \
+ CONFIG_CRYPTO_SHA256=y \
+ CONFIG_CRYPTO_SHA512=y \
+ CONFIG_CRYPTO_SHA3=y \
+ CONFIG_CRYPTO_HMAC=y \
+ CONFIG_INET_ESP=y
+ DEPENDS:= \
+ @TARGET_mediatek \
+ +strongswan \
+ +strongswan-default
+ $(call AddDepends/crypto)
+endef
+
+define KernelPackage/crypto-eip/description
+ Enable crypto engine to accelerate encrypt/decrypt. Support look aside
+ mode (semi-HW) and inline mode (pure-HW). Look aside mode is bind with
+ Linux Crypto API and support AES, DES, SHA1, and SHA2 algorithms. In-
+ line mode only support ESP Tunnel mode (single tunnel) now.
+endef
+
+define KernelPackage/crypto-eip/config
+ source "$(SOURCE)/Config.in"
+endef
+
+define KernelPackage/crypto-eip-inline
+ CATEGORY:=MTK Properties
+ SUBMENU:=Drivers
+ TITLE:= EIP-197 Crypto Engine Inline Driver
+ KCONFIG:= \
+ CONFIG_INET_ESP_OFFLOAD=y
+ DEPENDS:= \
+ @CRYPTO_OFFLOAD_INLINE \
+ kmod-crypto-eip \
+ kmod-crypto-eip-ddk \
+ +kmod-pce
+ FILES:=$(PKG_BUILD_DIR)/crypto-eip-inline.ko
+ $(call AddDepends/crypto)
+endef
+
+define KernelPackage/crypto-eip-inline/description
+ EIP197 inline mode. HW offload for IPsec ESP Tunnel mode.
+endef
diff --git a/package-21.02/kernel/crypto-eip/src/Kconfig b/package-21.02/kernel/crypto-eip/src/Kconfig
new file mode 100644
index 0000000..5dbbc5f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/Kconfig
@@ -0,0 +1,8 @@
+config MTK_CRYPTO_EIP_INLINE
+ tristate "Mediatek Crypto EIP Inline"
+ help
+ Support for Mediatek driver to control inline crypto HW offload
+ engine EIP197. The HW offload engine support IPsec ESP inline
+ offload. Currently, it only support ESP Tunnel and transport mode.
+ The driver cooperate XFRM offload framework with Mediatek HNAT
+ driver to offload ESP protocol.
diff --git a/package-21.02/kernel/crypto-eip/src/Makefile b/package-21.02/kernel/crypto-eip/src/Makefile
new file mode 100644
index 0000000..6beba79
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/Makefile
@@ -0,0 +1,17 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+obj-$(CONFIG_MTK_CRYPTO_EIP_INLINE) += crypto-eip-inline.o
+
+ccflags-y += -I$(src)/inc
+
+crypto-eip-inline-y += init.o
+crypto-eip-inline-y += ddk-wrapper.o
+
+crypto-eip-inline-$(CONFIG_CRYPTO_XFRM_OFFLOAD_MTK_PCE) += xfrm-offload.o
+
+include $(wildcard $(src)/*.mk)
diff --git a/package-21.02/kernel/crypto-eip/src/ddk-wrapper.c b/package-21.02/kernel/crypto-eip/src/ddk-wrapper.c
new file mode 100644
index 0000000..d923693
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk-wrapper.c
@@ -0,0 +1,573 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#include <crypto/aes.h>
+#include <crypto/hash.h>
+#include <crypto/hmac.h>
+#include <crypto/md5.h>
+#include <linux/delay.h>
+
+#include <crypto-eip/ddk/slad/api_pcl.h>
+#include <crypto-eip/ddk/slad/api_pcl_dtl.h>
+#include <crypto-eip/ddk/slad/api_pec.h>
+#include <crypto-eip/ddk/slad/api_driver197_init.h>
+
+#include "crypto-eip/crypto-eip.h"
+#include "crypto-eip/ddk-wrapper.h"
+#include "crypto-eip/internal.h"
+#include "crypto-eip/crypto-eip197-inline-ddk.h"
+
+static bool crypto_iotoken_create(IOToken_Input_Dscr_t * const dscr_p,
+ void * const ext_p, u32 *data_p,
+ PEC_CommandDescriptor_t * const pec_cmd_dscr)
+{
+ int IOTokenRc;
+
+ dscr_p->InPacket_ByteCount = pec_cmd_dscr->SrcPkt_ByteCount;
+ dscr_p->Ext_p = ext_p;
+
+ IOTokenRc = IOToken_Create(dscr_p, data_p);
+ if (IOTokenRc < 0) {
+ CRYPTO_ERR("IOToken_Create error %d\n", IOTokenRc);
+ return false;
+ }
+
+ pec_cmd_dscr->InputToken_p = data_p;
+
+ return true;
+}
+
+unsigned int crypto_pe_get_one(IOToken_Output_Dscr_t *const OutTokenDscr_p,
+ u32 *OutTokenData_p,
+ PEC_ResultDescriptor_t *RD_p)
+{
+ int LoopCounter = MTK_EIP197_INLINE_NOF_TRIES;
+ int IOToken_Rc;
+ PEC_Status_t pecres;
+
+ ZEROINIT(*OutTokenDscr_p);
+ ZEROINIT(*RD_p);
+
+ /* Link data structures */
+ RD_p->OutputToken_p = OutTokenData_p;
+
+ while (LoopCounter > 0) {
+ /* Try to get the processed packet from the driver */
+ unsigned int Counter = 0;
+
+ pecres = PEC_Packet_Get(PEC_INTERFACE_ID, RD_p, 1, &Counter);
+ if (pecres != PEC_STATUS_OK) {
+ /* IO error */
+ CRYPTO_ERR("PEC_Packet_Get error %d\n", pecres);
+ return 0;
+ }
+
+ if (Counter) {
+ IOToken_Rc = IOToken_Parse(OutTokenData_p, OutTokenDscr_p);
+ if (IOToken_Rc < 0) {
+ /* IO error */
+ CRYPTO_ERR("IOToken_Parse error %d\n", IOToken_Rc);
+ return 0;
+ }
+
+ if (OutTokenDscr_p->ErrorCode != 0) {
+ /* Packet process error */
+ CRYPTO_ERR("Result descriptor error 0x%x\n",
+ OutTokenDscr_p->ErrorCode);
+ return 0;
+ }
+
+ /* packet received */
+ return Counter;
+ }
+
+ /* Wait for MTK_EIP197_PKT_GET_TIMEOUT_MS milliseconds */
+ udelay(MTK_EIP197_PKT_GET_TIMEOUT_MS * 1000);
+ LoopCounter--;
+ }
+
+ CRYPTO_ERR("Timeout when reading packet\n");
+
+ /* IO error (timeout, not result packet received) */
+ return 0;
+}
+
+
+bool crypto_basic_hash(SABuilder_Auth_t HashAlgo, uint8_t *Input_p,
+ unsigned int InputByteCount, uint8_t *Output_p,
+ unsigned int OutputByteCount, bool fFinalize)
+{
+ SABuilder_Params_Basic_t ProtocolParams;
+ SABuilder_Params_t params;
+ unsigned int SAWords = 0;
+ static uint8_t DummyAuthKey[64];
+ int rc;
+
+ DMABuf_Properties_t DMAProperties = {0, 0, 0, 0};
+ DMABuf_HostAddress_t TokenHostAddress;
+ DMABuf_HostAddress_t PktHostAddress;
+ DMABuf_HostAddress_t SAHostAddress;
+ DMABuf_Status_t DMAStatus;
+
+ DMABuf_Handle_t TokenHandle = {0};
+ DMABuf_Handle_t PktHandle = {0};
+ DMABuf_Handle_t SAHandle = {0};
+
+ unsigned int TokenMaxWords = 0;
+ unsigned int TokenHeaderWord;
+ unsigned int TokenWords = 0;
+ unsigned int TCRWords = 0;
+ void *TCRData = 0;
+
+ TokenBuilder_Params_t TokenParams;
+ PEC_CommandDescriptor_t Cmd;
+ PEC_ResultDescriptor_t Res;
+ unsigned int count;
+
+ u32 OutputToken[IOTOKEN_IN_WORD_COUNT];
+ u32 InputToken[IOTOKEN_IN_WORD_COUNT];
+ IOToken_Output_Dscr_t OutTokenDscr;
+ IOToken_Input_Dscr_t InTokenDscr;
+ void *InTokenDscrExt_p = NULL;
+
+#ifdef CRYPTO_IOTOKEN_EXT
+ IOToken_Input_Dscr_Ext_t InTokenDscrExt;
+
+ ZEROINIT(InTokenDscrExt);
+ InTokenDscrExt_p = &InTokenDscrExt;
+#endif
+ ZEROINIT(InTokenDscr);
+ ZEROINIT(OutTokenDscr);
+
+ rc = SABuilder_Init_Basic(¶ms, &ProtocolParams, SAB_DIRECTION_OUTBOUND);
+ if (rc) {
+ CRYPTO_ERR("SABuilder_Init_Basic failed: %d\n", rc);
+ goto error_exit;
+ }
+
+ params.AuthAlgo = HashAlgo;
+ params.AuthKey1_p = DummyAuthKey;
+
+ if (!fFinalize)
+ params.flags |= SAB_FLAG_HASH_SAVE | SAB_FLAG_HASH_INTERMEDIATE;
+ params.flags |= SAB_FLAG_SUPPRESS_PAYLOAD;
+ ProtocolParams.ICVByteCount = OutputByteCount;
+
+ rc = SABuilder_GetSizes(¶ms, &SAWords, NULL, NULL);
+ if (rc) {
+ CRYPTO_ERR("SA not created because of size errors: %d\n", rc);
+ goto error_exit;
+ }
+
+ DMAProperties.fCached = true;
+ DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT;
+ DMAProperties.Bank = MTK_EIP197_INLINE_BANK_TRANSFORM;
+ DMAProperties.Size = MAX(4*SAWords, 256);
+
+ DMAStatus = DMABuf_Alloc(DMAProperties, &SAHostAddress, &SAHandle);
+ if (DMAStatus != DMABUF_STATUS_OK) {
+ rc = 1;
+ CRYPTO_ERR("Allocation of SA failed: %d\n", DMAStatus);
+ goto error_exit;
+ }
+
+ rc = SABuilder_BuildSA(¶ms, (u32 *)SAHostAddress.p, NULL, NULL);
+ if (rc) {
+ CRYPTO_ERR("SA not created because of errors: %d\n", rc);
+ goto error_exit;
+ }
+
+ rc = TokenBuilder_GetContextSize(¶ms, &TCRWords);
+ if (rc) {
+ CRYPTO_ERR("TokenBuilder_GetContextSize returned errors: %d\n", rc);
+ goto error_exit;
+ }
+
+ TCRData = kmalloc(4 * TCRWords, GFP_KERNEL);
+ if (!TCRData) {
+ rc = 1;
+ CRYPTO_ERR("Allocation of TCR failed\n");
+ goto error_exit;
+ }
+
+ rc = TokenBuilder_BuildContext(¶ms, TCRData);
+ if (rc) {
+ CRYPTO_ERR("TokenBuilder_BuildContext failed: %d\n", rc);
+ goto error_exit;
+ }
+
+ rc = TokenBuilder_GetSize(TCRData, &TokenMaxWords);
+ if (rc) {
+ CRYPTO_ERR("TokenBuilder_GetSize failed: %d\n", rc);
+ goto error_exit;
+ }
+
+ DMAProperties.fCached = true;
+ DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT;
+ DMAProperties.Bank = MTK_EIP197_INLINE_BANK_TOKEN;
+ DMAProperties.Size = 4*TokenMaxWords;
+
+ DMAStatus = DMABuf_Alloc(DMAProperties, &TokenHostAddress, &TokenHandle);
+ if (DMAStatus != DMABUF_STATUS_OK) {
+ rc = 1;
+ CRYPTO_ERR("Allocation of token builder failed: %d\n", DMAStatus);
+ goto error_exit;
+ }
+
+ DMAProperties.fCached = true;
+ DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT;
+ DMAProperties.Bank = MTK_EIP197_INLINE_BANK_PACKET;
+ DMAProperties.Size = MAX(InputByteCount, OutputByteCount);
+
+ DMAStatus = DMABuf_Alloc(DMAProperties, &PktHostAddress, &PktHandle);
+ if (DMAStatus != DMABUF_STATUS_OK) {
+ rc = 1;
+ CRYPTO_ERR("Allocation of source packet buffer failed: %d\n",
+ DMAStatus);
+ goto error_exit;
+ }
+
+ rc = PEC_SA_Register(PEC_INTERFACE_ID, SAHandle, DMABuf_NULLHandle,
+ DMABuf_NULLHandle);
+ if (rc != PEC_STATUS_OK) {
+ CRYPTO_ERR("PEC_SA_Register failed: %d\n", rc);
+ goto error_exit;
+ }
+
+ memcpy(PktHostAddress.p, Input_p, InputByteCount);
+
+ ZEROINIT(TokenParams);
+ TokenParams.PacketFlags |= (TKB_PACKET_FLAG_HASHFIRST
+ | TKB_PACKET_FLAG_HASHAPPEND);
+ if (fFinalize)
+ TokenParams.PacketFlags |= TKB_PACKET_FLAG_HASHFINAL;
+
+ rc = TokenBuilder_BuildToken(TCRData, (u8 *) PktHostAddress.p,
+ InputByteCount, &TokenParams,
+ (u32 *) TokenHostAddress.p,
+ &TokenWords, &TokenHeaderWord);
+ if (rc != TKB_STATUS_OK) {
+ CRYPTO_ERR("Token builder failed: %d\n", rc);
+ goto error_exit_unregister;
+ }
+
+ ZEROINIT(Cmd);
+ Cmd.Token_Handle = TokenHandle;
+ Cmd.Token_WordCount = TokenWords;
+ Cmd.SrcPkt_Handle = PktHandle;
+ Cmd.SrcPkt_ByteCount = InputByteCount;
+ Cmd.DstPkt_Handle = PktHandle;
+ Cmd.SA_Handle1 = SAHandle;
+ Cmd.SA_Handle2 = DMABuf_NULLHandle;
+
+
+#if defined(CRYPTO_IOTOKEN_EXT)
+ InTokenDscrExt.HW_Services = IOTOKEN_CMD_PKT_LAC;
+#endif
+ InTokenDscr.TknHdrWordInit = TokenHeaderWord;
+
+ if (!crypto_iotoken_create(&InTokenDscr,
+ InTokenDscrExt_p,
+ InputToken,
+ &Cmd)) {
+ rc = 1;
+ goto error_exit_unregister;
+ }
+
+ rc = PEC_Packet_Put(PEC_INTERFACE_ID, &Cmd, 1, &count);
+ if (rc != PEC_STATUS_OK && count != 1) {
+ rc = 1;
+ CRYPTO_ERR("PEC_Packet_Put error: %d\n", rc);
+ goto error_exit_unregister;
+ }
+
+ if (crypto_pe_get_one(&OutTokenDscr, OutputToken, &Res) < 1) {
+ rc = 1;
+ CRYPTO_ERR("error from crypto_pe_get_one\n");
+ goto error_exit_unregister;
+ }
+ memcpy(Output_p, PktHostAddress.p, OutputByteCount);
+
+error_exit_unregister:
+ PEC_SA_UnRegister(PEC_INTERFACE_ID, SAHandle, DMABuf_NULLHandle,
+ DMABuf_NULLHandle);
+
+error_exit:
+ DMABuf_Release(SAHandle);
+ DMABuf_Release(TokenHandle);
+ DMABuf_Release(PktHandle);
+
+ if (TCRData != NULL)
+ kfree(TCRData);
+
+ return rc == 0;
+}
+
+bool crypto_hmac_precompute(SABuilder_Auth_t AuthAlgo,
+ uint8_t *AuthKey_p,
+ unsigned int AuthKeyByteCount,
+ uint8_t *Inner_p,
+ uint8_t *Outer_p)
+{
+ SABuilder_Auth_t HashAlgo;
+ unsigned int blocksize, hashsize, digestsize;
+ static uint8_t pad_block[128], hashed_key[128];
+ unsigned int i;
+
+ switch (AuthAlgo) {
+ case SAB_AUTH_HMAC_MD5:
+ HashAlgo = SAB_AUTH_HASH_MD5;
+ blocksize = 64;
+ hashsize = 16;
+ digestsize = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA1:
+ HashAlgo = SAB_AUTH_HASH_SHA1;
+ blocksize = 64;
+ hashsize = 20;
+ digestsize = 20;
+ break;
+ case SAB_AUTH_HMAC_SHA2_224:
+ HashAlgo = SAB_AUTH_HASH_SHA2_224;
+ blocksize = 64;
+ hashsize = 28;
+ digestsize = 32;
+ break;
+ case SAB_AUTH_HMAC_SHA2_256:
+ HashAlgo = SAB_AUTH_HASH_SHA2_256;
+ blocksize = 64;
+ hashsize = 32;
+ digestsize = 32;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ HashAlgo = SAB_AUTH_HASH_SHA2_384;
+ blocksize = 128;
+ hashsize = 48;
+ digestsize = 64;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ HashAlgo = SAB_AUTH_HASH_SHA2_512;
+ blocksize = 128;
+ hashsize = 64;
+ digestsize = 64;
+ break;
+ default:
+ CRYPTO_ERR("Unknown HMAC algorithm\n");
+ return false;
+ }
+
+ memset(hashed_key, 0, blocksize);
+ if (AuthKeyByteCount <= blocksize) {
+ memcpy(hashed_key, AuthKey_p, AuthKeyByteCount);
+ } else {
+ if (!crypto_basic_hash(HashAlgo, AuthKey_p, AuthKeyByteCount,
+ hashed_key, hashsize, true))
+ return false;
+ }
+
+ for (i = 0; i < blocksize; i++)
+ pad_block[i] = hashed_key[i] ^ 0x36;
+
+ if (!crypto_basic_hash(HashAlgo, pad_block, blocksize,
+ Inner_p, digestsize, false))
+ return false;
+
+ for (i = 0; i < blocksize; i++)
+ pad_block[i] = hashed_key[i] ^ 0x5c;
+
+ if (!crypto_basic_hash(HashAlgo, pad_block, blocksize,
+ Outer_p, digestsize, false))
+ return false;
+
+ return true;
+}
+
+static SABuilder_Crypto_t set_crypto_algo(struct xfrm_algo *ealg)
+{
+ if (strcmp(ealg->alg_name, "cbc(des)") == 0)
+ return SAB_CRYPTO_DES;
+ else if (strcmp(ealg->alg_name, "cbc(aes)") == 0)
+ return SAB_CRYPTO_AES;
+ else if (strcmp(ealg->alg_name, "cbc(des3_ede)") == 0)
+ return SAB_CRYPTO_3DES;
+
+ return SAB_CRYPTO_NULL;
+}
+
+static bool set_auth_algo(struct xfrm_algo_auth *aalg, SABuilder_Params_t *params,
+ uint8_t *inner, uint8_t *outer)
+{
+ if (strcmp(aalg->alg_name, "hmac(sha1)") == 0) {
+ params->AuthAlgo = SAB_AUTH_HMAC_SHA1;
+ inner = kcalloc(SHA1_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ outer = kcalloc(SHA1_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ crypto_hmac_precompute(SAB_AUTH_HMAC_SHA1, &aalg->alg_key[0],
+ aalg->alg_key_len / 8, inner, outer);
+
+ params->AuthKey1_p = inner;
+ params->AuthKey2_p = outer;
+ } else if (strcmp(aalg->alg_name, "hmac(sha256)") == 0) {
+ params->AuthAlgo = SAB_AUTH_HMAC_SHA2_256;
+ inner = kcalloc(SHA256_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ outer = kcalloc(SHA256_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_256, &aalg->alg_key[0],
+ aalg->alg_key_len / 8, inner, outer);
+ params->AuthKey1_p = inner;
+ params->AuthKey2_p = outer;
+ } else if (strcmp(aalg->alg_name, "hmac(sha384)") == 0) {
+ params->AuthAlgo = SAB_AUTH_HMAC_SHA2_384;
+ inner = kcalloc(SHA384_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ outer = kcalloc(SHA384_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_384, &aalg->alg_key[0],
+ aalg->alg_key_len / 8, inner, outer);
+ params->AuthKey1_p = inner;
+ params->AuthKey2_p = outer;
+ } else if (strcmp(aalg->alg_name, "hmac(sha512)") == 0) {
+ params->AuthAlgo = SAB_AUTH_HMAC_SHA2_512;
+ inner = kcalloc(SHA512_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ outer = kcalloc(SHA512_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_512, &aalg->alg_key[0],
+ aalg->alg_key_len / 8, inner, outer);
+ params->AuthKey1_p = inner;
+ params->AuthKey2_p = outer;
+ } else if (strcmp(aalg->alg_name, "hmac(md5)") == 0) {
+ params->AuthAlgo = SAB_AUTH_HMAC_MD5;
+ inner = kcalloc(MD5_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ outer = kcalloc(MD5_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL);
+ crypto_hmac_precompute(SAB_AUTH_HMAC_MD5, &aalg->alg_key[0],
+ aalg->alg_key_len / 8, inner, outer);
+ params->AuthKey1_p = inner;
+ params->AuthKey2_p = outer;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+u32 *mtk_ddk_tr_ipsec_build(struct mtk_xfrm_params *xfrm_params, u32 ipsec_mode)
+{
+ struct xfrm_state *xs = xfrm_params->xs;
+ SABuilder_Params_IPsec_t ipsec_params;
+ SABuilder_Status_t sa_status;
+ SABuilder_Params_t params;
+ bool set_auth_success = false;
+ unsigned int SAWords = 0;
+ uint8_t *inner, *outer;
+
+ DMABuf_Status_t dma_status;
+ DMABuf_Properties_t dma_properties = {0, 0, 0, 0};
+ DMABuf_HostAddress_t sa_host_addr;
+
+ DMABuf_Handle_t sa_handle = {0};
+
+ sa_status = SABuilder_Init_ESP(¶ms,
+ &ipsec_params,
+ be32_to_cpu(xs->id.spi),
+ ipsec_mode,
+ SAB_IPSEC_IPV4,
+ xfrm_params->dir);
+
+ if (sa_status != SAB_STATUS_OK) {
+ pr_err("SABuilder_Init_ESP failed\n");
+ sa_handle.p = NULL;
+ return (u32 *) sa_handle.p;
+ }
+
+ /* Add crypto key and parameters */
+ params.CryptoAlgo = set_crypto_algo(xs->ealg);
+ params.CryptoMode = SAB_CRYPTO_MODE_CBC;
+ params.KeyByteCount = xs->ealg->alg_key_len / 8;
+ params.Key_p = xs->ealg->alg_key;
+
+ /* Add authentication key and parameters */
+ set_auth_success = set_auth_algo(xs->aalg, ¶ms, inner, outer);
+ if (set_auth_success != true) {
+ CRYPTO_ERR("Set Auth Algo failed\n");
+ sa_handle.p = NULL;
+ return (u32 *) sa_handle.p;
+ }
+
+ ipsec_params.IPsecFlags |= (SAB_IPSEC_PROCESS_IP_HEADERS
+ | SAB_IPSEC_EXT_PROCESSING);
+ if (ipsec_mode == SAB_IPSEC_TUNNEL) {
+ ipsec_params.SrcIPAddr_p = (uint8_t *) &xs->props.saddr.a4;
+ ipsec_params.DestIPAddr_p = (uint8_t *) &xs->id.daddr.a4;
+ }
+
+ sa_status = SABuilder_GetSizes(¶ms, &SAWords, NULL, NULL);
+ if (sa_status != SAB_STATUS_OK) {
+ CRYPTO_ERR("SA not created because of size errors\n");
+ sa_handle.p = NULL;
+ return (u32 *) sa_handle.p;
+ }
+
+ dma_properties.fCached = true;
+ dma_properties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT;
+ dma_properties.Bank = MTK_EIP197_INLINE_BANK_TRANSFORM;
+ dma_properties.Size = SAWords * sizeof(u32);
+
+ dma_status = DMABuf_Alloc(dma_properties, &sa_host_addr, &sa_handle);
+ if (dma_status != DMABUF_STATUS_OK) {
+ CRYPTO_ERR("Allocation of SA failed\n");
+ /* goto error_exit; */
+ sa_handle.p = NULL;
+ return (u32 *) sa_handle.p;
+ }
+
+ sa_status = SABuilder_BuildSA(¶ms, (u32 *) sa_host_addr.p, NULL, NULL);
+ if (sa_status != SAB_STATUS_OK) {
+ CRYPTO_ERR("SA not created because of errors\n");
+ sa_handle.p = NULL;
+ return (u32 *) sa_handle.p;
+ }
+
+ kfree(inner);
+ kfree(outer);
+ return (u32 *) sa_host_addr.p;
+}
+
+int mtk_ddk_pec_init(void)
+{
+ PEC_InitBlock_t pec_init_blk = {0, 0, false};
+ PEC_Capabilities_t pec_cap;
+ PEC_Status_t pec_sta;
+ u32 i = MTK_EIP197_INLINE_NOF_TRIES;
+
+ while (i) {
+ pec_sta = PEC_Init(PEC_INTERFACE_ID, &pec_init_blk);
+ if (pec_sta == PEC_STATUS_OK) {
+ CRYPTO_INFO("PEC_INIT ok!\n");
+ break;
+ } else if (pec_sta != PEC_STATUS_OK && pec_sta != PEC_STATUS_BUSY) {
+ return pec_sta;
+ }
+
+ mdelay(MTK_EIP197_INLINE_RETRY_DELAY_MS);
+ i--;
+ }
+
+ if (!i) {
+ CRYPTO_ERR("PEC could not be initialized: %d\n", pec_sta);
+ return pec_sta;
+ }
+
+ pec_sta = PEC_Capabilities_Get(&pec_cap);
+ if (pec_sta != PEC_STATUS_OK) {
+ CRYPTO_ERR("PEC capability could not be obtained: %d\n", pec_sta);
+ return pec_sta;
+ }
+
+ CRYPTO_INFO("PEC Capabilities: %s\n", pec_cap.szTextDescription);
+
+ return 0;
+}
+
+void mtk_ddk_pec_deinit(void)
+{
+}
diff --git a/package-21.02/kernel/crypto-eip/src/ddk.mk b/package-21.02/kernel/crypto-eip/src/ddk.mk
new file mode 100644
index 0000000..7c2a3c6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk.mk
@@ -0,0 +1,8 @@
+# SPDX-Liscense-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2023 MediaTek Inc.
+#
+# Author: Chris.Chou <chris.chou@mediatek.com>
+# Ren-Ting Wang <ren-ting.wang@mediatek.com>
+
+obj-$(CONFIG_RAMBUS_DDK) += ddk/
diff --git a/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip.h b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip.h
new file mode 100644
index 0000000..24f6f91
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#ifndef _CRYPTO_EIP_H_
+#define _CRYPTO_EIP_H_
+
+#include <crypto/sha.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <net/xfrm.h>
+
+#include "crypto-eip/crypto-eip197-inline-ddk.h"
+
+struct mtk_crypto;
+
+extern struct mtk_crypto mcrypto;
+
+#define TRANSFORM_RECORD_LEN 64
+
+#define MAX_TUNNEL_NUM 10
+#define PACKET_INBOUND 1
+#define PACKET_OUTBOUND 2
+
+#define HASH_CACHE_SIZE SHA512_BLOCK_SIZE
+
+#define EIP197_FORCE_CLK_ON2 (0xfffd8)
+#define EIP197_FORCE_CLK_ON (0xfffe8)
+#define EIP197_AUTO_LOOKUP_1 (0xfffffffc)
+#define EIP197_AUTO_LOOKUP_2 (0xffffffff)
+
+struct mtk_crypto {
+ struct mtk_eth *eth;
+ void __iomem *crypto_base;
+ void __iomem *eth_base;
+};
+
+struct mtk_xfrm_params {
+ struct xfrm_state *xs;
+ struct list_head node;
+ struct cdrt_entry *cdrt;
+
+ u32 *p_tr; /* pointer to transform record */
+ u32 dir; /* SABuilder_Direction_t */
+};
+
+void crypto_eth_write(u32 reg, u32 val);
+
+/* xfrm callback functions */
+int mtk_xfrm_offload_state_add(struct xfrm_state *xs);
+void mtk_xfrm_offload_state_delete(struct xfrm_state *xs);
+void mtk_xfrm_offload_state_free(struct xfrm_state *xs);
+void mtk_xfrm_offload_state_tear_down(void);
+int mtk_xfrm_offload_policy_add(struct xfrm_policy *xp);
+bool mtk_xfrm_offload_ok(struct sk_buff *skb, struct xfrm_state *xs);
+#endif /* _CRYPTO_EIP_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip197-inline-ddk.h b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip197-inline-ddk.h
new file mode 100644
index 0000000..00fb1a8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/crypto-eip197-inline-ddk.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#ifndef _CRYPTO_EIP197_INLINE_DDK_H_
+#define _CRYPTO_EIP197_INLINE_DDK_H_
+
+#include <crypto-eip/ddk/basic_defs.h>
+#include <crypto-eip/ddk/configs/cs_ddk197.h>
+#include <crypto-eip/ddk/configs/cs_driver_ext.h>
+#include <crypto-eip/ddk/configs/cs_adapter.h>
+#include <crypto-eip/ddk/libc/clib.h>
+#include <crypto-eip/ddk/kit/builder/sa/sa_builder.h>
+#include <crypto-eip/ddk/kit/builder/sa/sa_builder_ipsec.h>
+#include <crypto-eip/ddk/kit/builder/sa/sa_builder_basic.h>
+#include <crypto-eip/ddk/kit/builder/sa/sa_builder_params_basic.h>
+#include <crypto-eip/ddk/kit/builder/token/token_builder.h>
+#include <crypto-eip/ddk/kit/iotoken/iotoken.h>
+#include <crypto-eip/ddk/kit/iotoken/iotoken_ext.h>
+#include <crypto-eip/ddk/slad/api_dmabuf.h>
+#include <crypto-eip/ddk/slad/api_pcl.h>
+#include <crypto-eip/ddk/slad/api_pcl_dtl.h>
+#include <crypto-eip/ddk/slad/api_pec.h>
+#include <crypto-eip/ddk/log/log.h>
+
+#ifdef DDK_EIP197_FW33_FEATURES
+#define MTK_EIP197_INLINE_STRIP_PADDING
+#endif
+
+#define CRYPTO_IOTOKEN_EXT
+
+#define MTK_EIP197_INLINE_BANK_PACKET 0
+
+#define MTK_EIP197_INLINE_BANK_TRANSFORM 1
+#define MTK_EIP197_INLINE_BANK_TOKEN 0
+
+/* Delay in milliseconds between tries to receive the packet */
+#define MTK_EIP197_INLINE_RETRY_DELAY_MS 2
+#define MTK_EIP197_PKT_GET_TIMEOUT_MS 2
+
+/* Maximum number of tries to receive the packet. */
+#define MTK_EIP197_INLINE_NOF_TRIES 10
+
+#define MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT 16
+
+/* PEC Configuration */
+#ifdef DDK_PEC_IF_ID
+#define PEC_INTERFACE_ID DDK_PEC_IF_ID
+#else
+#define PEC_INTERFACE_ID 0
+#endif
+#define PEC_REDIRECT_INTERFACE 7
+#define PEC_INLINE_INTERFACE 15
+
+#define PCL_INTERFACE_ID 0
+#endif /* _CRYPTO_EIP197_INLINE_DDK_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/ddk-wrapper.h b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/ddk-wrapper.h
new file mode 100644
index 0000000..db2b84f
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/ddk-wrapper.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#ifndef _CRYPTO_EIP_DDK_WRAPPER_H_
+#define _CRYPTO_EIP_DDK_WRAPPER_H_
+
+#include "crypto-eip.h"
+
+u32 *mtk_ddk_tr_ipsec_build(struct mtk_xfrm_params *xfrm_params, u32 ipsec_mod);
+
+int mtk_ddk_pec_init(void);
+void mtk_ddk_pec_deinit(void);
+#endif /* _CRYPTO_EIP_DDK_WRAPPER_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/internal.h b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/internal.h
new file mode 100644
index 0000000..e843841
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/inc/crypto-eip/internal.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#ifndef _CRYPTO_EIP_INTERNAL_H_
+#define _CRYPTO_EIP_INTERNAL_H_
+
+#include <linux/device.h>
+
+extern struct device *crypto_dev;
+
+#define CRYPTO_DBG(fmt, ...) dev_dbg(crypto_dev, fmt, ##__VA_ARGS__)
+#define CRYPTO_INFO(fmt, ...) dev_info(crypto_dev, fmt, ##__VA_ARGS__)
+#define CRYPTO_NOTICE(fmt, ...) dev_notice(crypto_dev, fmt, ##__VA_ARGS__)
+#define CRYPTO_WARN(fmt, ...) dev_warn(crypto_dev, fmt, ##__VA_ARGS__)
+#define CRYPTO_ERR(fmt, ...) dev_err(crypto_dev, fmt, ##__VA_ARGS__)
+
+#define setbits(addr, set) writel(readl(addr) | (set), (addr))
+#define clrbits(addr, clr) writel(readl(addr) & ~(clr), (addr))
+#define clrsetbits(addr, clr, set) writel((readl(addr) & ~(clr)) | (set), (addr))
+#endif /* _CRYPTO_EIP_INTERNAL_H_ */
diff --git a/package-21.02/kernel/crypto-eip/src/init.c b/package-21.02/kernel/crypto-eip/src/init.c
new file mode 100644
index 0000000..cc53a39
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/init.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <mtk_eth_soc.h>
+#include <mtk_hnat/hnat.h>
+
+#include <crypto-eip/ddk/configs/cs_hwpal_ext.h>
+
+#include "crypto-eip/crypto-eip.h"
+#include "crypto-eip/ddk-wrapper.h"
+#include "crypto-eip/internal.h"
+
+#define DRIVER_AUTHOR "Ren-Ting Wang <ren-ting.wang@mediatek.com, " \
+ "Chris.Chou <chris.chou@mediatek.com"
+
+struct mtk_crypto mcrypto;
+struct device *crypto_dev;
+
+inline void crypto_eth_write(u32 reg, u32 val)
+{
+ writel(val, mcrypto.eth_base + reg);
+}
+
+static inline void crypto_eip_write(u32 reg, u32 val)
+{
+ writel(val, mcrypto.crypto_base + reg);
+}
+
+static inline void crypto_eip_set(u32 reg, u32 mask)
+{
+ setbits(mcrypto.crypto_base + reg, mask);
+}
+
+static inline void crypto_eip_clr(u32 reg, u32 mask)
+{
+ clrbits(mcrypto.crypto_base + reg, mask);
+}
+
+static inline void crypto_eip_rmw(u32 reg, u32 mask, u32 val)
+{
+ clrsetbits(mcrypto.crypto_base + reg, mask, val);
+}
+
+static inline u32 crypto_eip_read(u32 reg)
+{
+ return readl(mcrypto.crypto_base + reg);
+}
+
+static bool mtk_crypto_eip_offloadable(struct sk_buff *skb)
+{
+ /* TODO: check is esp */
+ return true;
+}
+
+static const struct xfrmdev_ops mtk_xfrmdev_ops = {
+ .xdo_dev_state_add = mtk_xfrm_offload_state_add,
+ .xdo_dev_state_delete = mtk_xfrm_offload_state_delete,
+ .xdo_dev_state_free = mtk_xfrm_offload_state_free,
+ .xdo_dev_offload_ok = mtk_xfrm_offload_ok,
+
+ /* Not support at v5.4*/
+ .xdo_dev_policy_add = mtk_xfrm_offload_policy_add,
+};
+
+static void mtk_crypto_xfrm_offload_deinit(struct mtk_eth *eth)
+{
+ int i;
+
+ mtk_crypto_offloadable = NULL;
+
+ for (i = 0; i < MTK_MAC_COUNT; i++) {
+ eth->netdev[i]->xfrmdev_ops = NULL;
+ eth->netdev[i]->features &= (~NETIF_F_HW_ESP);
+ eth->netdev[i]->hw_enc_features &= (~NETIF_F_HW_ESP);
+ rtnl_lock();
+ netdev_change_features(eth->netdev[i]);
+ rtnl_unlock();
+ }
+}
+
+static void mtk_crypto_xfrm_offload_init(struct mtk_eth *eth)
+{
+ int i;
+
+ for (i = 0; i < MTK_MAC_COUNT; i++) {
+ eth->netdev[i]->xfrmdev_ops = &mtk_xfrmdev_ops;
+ eth->netdev[i]->features |= NETIF_F_HW_ESP;
+ eth->netdev[i]->hw_enc_features |= NETIF_F_HW_ESP;
+ rtnl_lock();
+ netdev_change_features(eth->netdev[i]);
+ rtnl_unlock();
+ }
+
+ mtk_crypto_offloadable = mtk_crypto_eip_offloadable;
+}
+
+static int __init mtk_crypto_eth_dts_init(struct platform_device *pdev)
+{
+ struct platform_device *eth_pdev;
+ struct device_node *crypto_node;
+ struct device_node *eth_node;
+ struct resource res;
+ int ret = 0;
+
+ crypto_node = pdev->dev.of_node;
+
+ eth_node = of_parse_phandle(crypto_node, "eth", 0);
+ if (!eth_node)
+ return -ENODEV;
+
+ eth_pdev = of_find_device_by_node(eth_node);
+ if (!eth_pdev) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!eth_pdev->dev.driver) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (of_address_to_resource(eth_node, 0, &res)) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ mcrypto.eth_base = devm_ioremap(&pdev->dev,
+ res.start, resource_size(&res));
+ if (!mcrypto.eth_base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ mcrypto.eth = platform_get_drvdata(eth_pdev);
+
+out:
+ of_node_put(eth_node);
+
+ return ret;
+}
+
+static int __init mtk_crypto_eip_dts_init(void)
+{
+ struct platform_device *crypto_pdev;
+ struct device_node *crypto_node;
+ struct resource res;
+ int ret;
+
+ crypto_node = of_find_compatible_node(NULL, NULL, HWPAL_PLATFORM_DEVICE_NAME);
+ if (!crypto_node)
+ return -ENODEV;
+
+ crypto_pdev = of_find_device_by_node(crypto_node);
+ if (!crypto_pdev) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* check crypto platform device is ready */
+ if (!crypto_pdev->dev.driver) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (of_address_to_resource(crypto_node, 0, &res)) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ mcrypto.crypto_base = devm_ioremap(&crypto_pdev->dev,
+ res.start, resource_size(&res));
+ if (!mcrypto.crypto_base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = mtk_crypto_eth_dts_init(crypto_pdev);
+ if (ret)
+ goto out;
+
+ crypto_dev = &crypto_pdev->dev;
+
+out:
+ of_node_put(crypto_node);
+
+ return ret;
+}
+
+static int __init mtk_crypto_eip_hw_init(void)
+{
+ crypto_eip_write(EIP197_FORCE_CLK_ON, 0xffffffff);
+
+ crypto_eip_write(EIP197_FORCE_CLK_ON2, 0xffffffff);
+
+ /* TODO: adjust AXI burst? */
+
+ mtk_ddk_pec_init();
+
+ return 0;
+}
+
+static void __exit mtk_crypto_eip_hw_deinit(void)
+{
+ mtk_ddk_pec_deinit();
+
+ crypto_eip_write(EIP197_FORCE_CLK_ON, 0);
+
+ crypto_eip_write(EIP197_FORCE_CLK_ON2, 0);
+}
+
+static int __init mtk_crypto_eip_init(void)
+{
+ int ret;
+
+ ret = mtk_crypto_eip_dts_init();
+ if (ret) {
+ CRYPTO_ERR("crypto-eip dts init failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = mtk_crypto_eip_hw_init();
+ if (ret) {
+ CRYPTO_ERR("crypto-eip hw init failed: %d\n", ret);
+ return ret;
+ }
+
+ mtk_crypto_xfrm_offload_init(mcrypto.eth);
+
+ CRYPTO_INFO("crypto-eip init done\n");
+
+ return ret;
+}
+
+static void __exit mtk_crypto_eip_exit(void)
+{
+ /* TODO: deactivate all tunnel */
+
+ mtk_crypto_xfrm_offload_deinit(mcrypto.eth);
+
+ mtk_crypto_eip_hw_deinit();
+}
+
+module_init(mtk_crypto_eip_init);
+module_exit(mtk_crypto_eip_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek Crypto EIP Control Driver");
+MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/package-21.02/kernel/crypto-eip/src/xfrm-offload.c b/package-21.02/kernel/crypto-eip/src/xfrm-offload.c
new file mode 100644
index 0000000..bd79147
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/xfrm-offload.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ * Author: Chris.Chou <chris.chou@mediatek.com>
+ * Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#include <linux/bitops.h>
+
+#include <mtk_eth_soc.h>
+#include <mtk_hnat/hnat.h>
+#include <mtk_hnat/nf_hnat_mtk.h>
+
+#include <pce/cdrt.h>
+#include <pce/cls.h>
+#include <pce/netsys.h>
+
+#include <crypto-eip/ddk/configs/cs_hwpal_ext.h>
+#include <crypto-eip/ddk/kit/iotoken/iotoken.h>
+#include <crypto-eip/ddk/kit/iotoken/iotoken_ext.h>
+
+#include "crypto-eip/crypto-eip.h"
+#include "crypto-eip/ddk-wrapper.h"
+#include "crypto-eip/internal.h"
+
+static LIST_HEAD(xfrm_params_head);
+
+static void mtk_xfrm_offload_cdrt_tear_down(struct mtk_xfrm_params *xfrm_params)
+{
+ memset(&xfrm_params->cdrt->desc, 0, sizeof(struct cdrt_desc));
+
+ mtk_pce_cdrt_entry_write(xfrm_params->cdrt);
+}
+
+static int mtk_xfrm_offload_cdrt_setup(struct mtk_xfrm_params *xfrm_params)
+{
+ struct cdrt_desc *cdesc = &xfrm_params->cdrt->desc;
+
+ cdesc->desc1.common.type = 3;
+ cdesc->desc1.token_len = 48;
+ cdesc->desc1.p_tr[0] = __pa(xfrm_params->p_tr) | 2;
+
+ cdesc->desc2.hw_srv = 2;
+ cdesc->desc2.allow_pad = 1;
+ cdesc->desc2.strip_pad = 1;
+
+ return mtk_pce_cdrt_entry_write(xfrm_params->cdrt);
+}
+
+static int mtk_xfrm_offload_cls_entry_setup(struct mtk_xfrm_params *xfrm_params)
+{
+ struct cls_entry esp_cls_entry = {
+ .entry = xfrm_params->cdrt->idx + 10, /* TODO: need update */
+ .cdesc = {
+ .fport = 0x3,
+ .tport_idx = 0x2,
+ .cdrt_idx = xfrm_params->cdrt->idx,
+
+ .l4_udp_hdr_nez_m = 0x1,
+ .l4_udp_hdr_nez = 0x1,
+ .l4_hdr_usr_data_m = 0xffffffff,
+ .l4_hdr_usr_data = be32_to_cpu(xfrm_params->xs->id.spi),
+ .l4_valid_m = 0x3,
+ .l4_valid = 0x3,
+ .l4_dport_m = 0x0,
+ .l4_dport = 0x0,
+ .tag_m = 0x3,
+ .tag = 0x1,
+ .dip_match_m = 0x0,
+ .dip_match = 0x0,
+ .l4_type_m = 0xff,
+ .l4_type = 0x32,
+ },
+ };
+
+ return mtk_pce_cls_entry_register(&esp_cls_entry);
+}
+
+static void mtk_xfrm_offload_context_tear_down(struct mtk_xfrm_params *xfrm_params)
+{
+ mtk_xfrm_offload_cdrt_tear_down(xfrm_params);
+
+ /* TODO: free context */
+ devm_kfree(crypto_dev, xfrm_params->p_tr);
+
+ /* TODO: transform record tear down */
+}
+
+static int mtk_xfrm_offload_context_setup(struct mtk_xfrm_params *xfrm_params)
+{
+ u32 *tr;
+ int ret;
+
+ xfrm_params->p_tr = devm_kcalloc(crypto_dev, sizeof(u32),
+ TRANSFORM_RECORD_LEN, GFP_KERNEL);
+ if (unlikely(!xfrm_params->p_tr))
+ return -ENOMEM;
+
+ switch (xfrm_params->xs->outer_mode.encap) {
+ case XFRM_MODE_TUNNEL:
+ tr = mtk_ddk_tr_ipsec_build(xfrm_params, SAB_IPSEC_TUNNEL);
+ break;
+ case XFRM_MODE_TRANSPORT:
+ tr = mtk_ddk_tr_ipsec_build(xfrm_params, SAB_IPSEC_TRANSPORT);
+ break;
+ default:
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ if (!tr) {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ memcpy(xfrm_params->p_tr, tr, sizeof(u32) * TRANSFORM_RECORD_LEN);
+
+ /* TODO: free tr */
+
+ return mtk_xfrm_offload_cdrt_setup(xfrm_params);
+
+err_out:
+ devm_kfree(crypto_dev, xfrm_params->p_tr);
+
+ return ret;
+}
+
+static int mtk_xfrm_offload_state_add_outbound(struct xfrm_state *xs,
+ struct mtk_xfrm_params *xfrm_params)
+{
+ int ret;
+
+ xfrm_params->cdrt = mtk_pce_cdrt_entry_alloc(CDRT_ENCRYPT);
+ if (IS_ERR(xfrm_params->cdrt))
+ return PTR_ERR(xfrm_params->cdrt);
+
+ xfrm_params->dir = SAB_DIRECTION_OUTBOUND;
+
+ ret = mtk_xfrm_offload_context_setup(xfrm_params);
+ if (ret)
+ goto free_cdrt;
+
+ return ret;
+
+free_cdrt:
+ mtk_pce_cdrt_entry_free(xfrm_params->cdrt);
+
+ return ret;
+}
+
+static int mtk_xfrm_offload_state_add_inbound(struct xfrm_state *xs,
+ struct mtk_xfrm_params *xfrm_params)
+{
+ int ret;
+
+ xfrm_params->cdrt = mtk_pce_cdrt_entry_alloc(CDRT_DECRYPT);
+ if (IS_ERR(xfrm_params->cdrt))
+ return PTR_ERR(xfrm_params->cdrt);
+
+ xfrm_params->dir = SAB_DIRECTION_INBOUND;
+
+ ret = mtk_xfrm_offload_context_setup(xfrm_params);
+ if (ret)
+ goto free_cdrt;
+
+ ret = mtk_xfrm_offload_cls_entry_setup(xfrm_params);
+ if (ret)
+ goto tear_down_context;
+
+ return ret;
+
+tear_down_context:
+ mtk_xfrm_offload_context_tear_down(xfrm_params);
+
+free_cdrt:
+ mtk_pce_cdrt_entry_free(xfrm_params->cdrt);
+
+ return ret;
+}
+
+int mtk_xfrm_offload_state_add(struct xfrm_state *xs)
+{
+ struct mtk_xfrm_params *xfrm_params;
+ int ret = 0;
+
+ /* TODO: maybe support IPv6 in the future? */
+ if (xs->props.family != AF_INET) {
+ CRYPTO_NOTICE("Only IPv4 xfrm states may be offloaded\n");
+ return -EINVAL;
+ }
+
+ /* only support ESP right now */
+ if (xs->id.proto != IPPROTO_ESP) {
+ CRYPTO_NOTICE("Unsupported protocol 0x%04x\n", xs->id.proto);
+ return -EINVAL;
+ }
+
+ /* only support tunnel mode or transport mode */
+ if (!(xs->outer_mode.encap == XFRM_MODE_TUNNEL
+ || xs->outer_mode.encap == XFRM_MODE_TRANSPORT))
+ return -EINVAL;
+
+ xfrm_params = devm_kzalloc(crypto_dev,
+ sizeof(struct mtk_xfrm_params),
+ GFP_KERNEL);
+ if (!xfrm_params)
+ return -ENOMEM;
+
+ xfrm_params->xs = xs;
+ INIT_LIST_HEAD(&xfrm_params->node);
+
+ if (xs->xso.flags & XFRM_OFFLOAD_INBOUND)
+ /* rx path */
+ ret = mtk_xfrm_offload_state_add_inbound(xs, xfrm_params);
+ else
+ /* tx path */
+ ret = mtk_xfrm_offload_state_add_outbound(xs, xfrm_params);
+
+ if (ret) {
+ devm_kfree(crypto_dev, xfrm_params);
+ goto out;
+ }
+
+ xs->xso.offload_handle = (unsigned long)xfrm_params;
+ list_add_tail(&xfrm_params->node, &xfrm_params_head);
+out:
+ return ret;
+}
+
+void mtk_xfrm_offload_state_delete(struct xfrm_state *xs)
+{
+}
+
+void mtk_xfrm_offload_state_free(struct xfrm_state *xs)
+{
+ struct mtk_xfrm_params *xfrm_params;
+
+ if (!xs->xso.offload_handle)
+ return;
+
+ xfrm_params = (struct mtk_xfrm_params *)xs->xso.offload_handle;
+
+ list_del(&xfrm_params->node);
+
+ if (xs->xso.flags & XFRM_OFFLOAD_INBOUND)
+ mtk_pce_cdrt_entry_free(xfrm_params->cdrt);
+
+ mtk_xfrm_offload_context_tear_down(xfrm_params);
+
+ mtk_pce_cdrt_entry_free(xfrm_params->cdrt);
+
+ devm_kfree(crypto_dev, xfrm_params);
+}
+
+void mtk_xfrm_offload_state_tear_down(void)
+{
+ struct mtk_xfrm_params *xfrm_params, *tmp;
+
+ list_for_each_entry_safe(xfrm_params, tmp, &xfrm_params_head, node)
+ mtk_xfrm_offload_state_free(xfrm_params->xs);
+}
+
+int mtk_xfrm_offload_policy_add(struct xfrm_policy *xp)
+{
+ return 0;
+}
+
+bool mtk_xfrm_offload_ok(struct sk_buff *skb,
+ struct xfrm_state *xs)
+{
+ struct mtk_xfrm_params *xfrm_params;
+
+ xfrm_params = (struct mtk_xfrm_params *)xs->xso.offload_handle;
+ skb_hnat_cdrt(skb) = xfrm_params->cdrt->idx;
+
+ return false;
+}