[][openwrt][mt7988][crypto][Refactor to unify EIP driver]
[Description]
Refactor to unify EIP driver.
1. Sync CAPWAP-DTLS functions for TOPS from neptune/eip_driver
2. Decoupled with hnat, IPSec inline mode is available even when hnat is
not activated now.
[Release-log]
N/A
Change-Id: Id53b483924fb90bc784570545b37e67e860a6024
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8868628
diff --git a/feed/kernel/crypto-eip/src/capwap-dtls-offload.c b/feed/kernel/crypto-eip/src/capwap-dtls-offload.c
new file mode 100644
index 0000000..5aef826
--- /dev/null
+++ b/feed/kernel/crypto-eip/src/capwap-dtls-offload.c
@@ -0,0 +1,184 @@
+// 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>
+ * Peter Wang <peterjy.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/crypto-eip.h"
+#include "crypto-eip/ddk-wrapper.h"
+#include "crypto-eip/internal.h"
+
+
+struct mtk_CDRT_DTLS_entry CDRT_DTLS_params;
+struct DTLSResourceMgmt *DTLSResourceTable[CAPWAP_MAX_TUNNEL_NUM];
+
+static int
+mtk_setup_cdrt_dtls(struct cdrt_entry *cdrt_entry_p, enum cdrt_type type)
+{
+ struct cdrt_desc *cdesc = &cdrt_entry_p->desc;
+
+ cdesc->desc1.dtls.pkt_len = 0;
+ cdesc->desc1.dtls.rsv1 = 0;
+ cdesc->desc1.dtls.capwap = 1;
+ if (type == CDRT_ENCRYPT)
+ cdesc->desc1.dtls.dir = 0;
+ else
+ cdesc->desc1.dtls.dir = 1;
+ cdesc->desc1.dtls.content_type = 3;
+ cdesc->desc1.dtls.type = 3;
+ cdesc->desc1.aad_len = 0;
+ cdesc->desc1.rsv1 = 0;
+ cdesc->desc1.app_id = 0;
+ cdesc->desc1.token_len = 0x30;
+ cdesc->desc1.rsv2 = 0;
+ cdesc->desc1.p_tr[0] = 0xfffffffc;
+ cdesc->desc1.p_tr[1] = 0xffffffff;
+
+ cdesc->desc2.usr = 0;
+ cdesc->desc2.rsv1 = 0;
+ cdesc->desc2.strip_pad = 1;
+ cdesc->desc2.allow_pad = 1;
+ cdesc->desc2.hw_srv = 0x28;
+ cdesc->desc2.rsv2 = 0;
+ cdesc->desc2.flow_lookup = 0;
+ cdesc->desc2.rsv3 = 0;
+ cdesc->desc2.ofs = 14;
+ cdesc->desc2.next_hdr = 0;
+ cdesc->desc2.fl = 0;
+ cdesc->desc2.ip4_chksum = 0;
+ if (type == CDRT_ENCRYPT)
+ cdesc->desc2.l4_chksum = 1;
+ else
+ cdesc->desc2.l4_chksum = 0;
+ cdesc->desc2.parse_eth = 0;
+ cdesc->desc2.keep_outer = 0;
+ cdesc->desc2.rsv4 = 0;
+ cdesc->desc2.rsv5[0] = 0;
+ cdesc->desc2.rsv5[1] = 0;
+
+ cdesc->desc3.option_meta[0] = 0x00000000;
+ cdesc->desc3.option_meta[1] = 0x00000000;
+ cdesc->desc3.option_meta[2] = 0x00000000;
+ cdesc->desc3.option_meta[3] = 0x00000000;
+
+ return mtk_pce_cdrt_entry_write(cdrt_entry_p);
+}
+
+
+static int
+mtk_add_cdrt_dtls(enum cdrt_type type)
+{
+ int ret = 0;
+ struct cdrt_entry *cdrt_entry_p = NULL;
+
+ cdrt_entry_p = mtk_pce_cdrt_entry_alloc(type);
+ if (cdrt_entry_p == NULL) {
+ CRYPTO_ERR("%s: mtk_pce_cdrt_entry_alloc failed!\n", __func__);
+ return 1;
+ }
+
+ ret = mtk_setup_cdrt_dtls(cdrt_entry_p, type);
+ if (ret)
+ goto free_cdrt;
+
+ if (type == CDRT_DECRYPT)
+ CDRT_DTLS_params.cdrt_inbound = cdrt_entry_p;
+ else
+ CDRT_DTLS_params.cdrt_outbound = cdrt_entry_p;
+ return ret;
+
+free_cdrt:
+ mtk_pce_cdrt_entry_free(cdrt_entry_p);
+
+ return ret;
+}
+
+
+void
+mtk_update_cdrt_idx(struct mtk_cdrt_idx_param *cdrt_idx_params_p)
+{
+ cdrt_idx_params_p->cdrt_idx_inbound = CDRT_DTLS_params.cdrt_inbound->idx;
+ cdrt_idx_params_p->cdrt_idx_outbound = CDRT_DTLS_params.cdrt_outbound->idx;
+}
+
+
+void
+mtk_dtls_capwap_init(void)
+{
+ int i = 0;
+ // init cdrt for dtls
+ if (mtk_add_cdrt_dtls(CDRT_DECRYPT))
+ CRYPTO_ERR("%s: CDRT DECRYPT for DTLS init failed!\n", __func__);
+
+ if (mtk_add_cdrt_dtls(CDRT_ENCRYPT))
+ CRYPTO_ERR("%s: CDRT ENCRYPT for DTLS init failed!\n", __func__);
+ // add hook function for tops driver
+#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
+ mtk_submit_SAparam_to_eip_driver = mtk_update_dtls_param;
+ mtk_remove_SAparam_to_eip_driver = mtk_remove_dtls_param;
+ mtk_update_cdrt_idx_from_eip_driver = mtk_update_cdrt_idx;
+#endif
+
+ // init table as NULL
+ for (i = 0; i < CAPWAP_MAX_TUNNEL_NUM; i++)
+ DTLSResourceTable[i] = NULL;
+}
+
+
+void
+mtk_dtls_capwap_deinit(void)
+{
+ int i = 0;
+ // Loop and check if all SA in table are freed
+ for (i = 0; i < CAPWAP_MAX_TUNNEL_NUM; i++) {
+ if (DTLSResourceTable[i] != NULL)
+ mtk_ddk_remove_dtls_param(&DTLSResourceTable[i]);
+ }
+
+ if (CDRT_DTLS_params.cdrt_inbound != NULL)
+ mtk_pce_cdrt_entry_free(CDRT_DTLS_params.cdrt_inbound);
+ if (CDRT_DTLS_params.cdrt_outbound != NULL)
+ mtk_pce_cdrt_entry_free(CDRT_DTLS_params.cdrt_outbound);
+#if defined(CONFIG_MTK_TOPS_CAPWAP_DTLS)
+ mtk_update_cdrt_idx_from_eip_driver = NULL;
+ mtk_submit_SAparam_to_eip_driver = NULL;
+ mtk_remove_SAparam_to_eip_driver = NULL;
+#endif
+}
+
+void
+mtk_update_dtls_param(struct DTLS_param *DTLSParam_p, int TnlIdx)
+{
+ char *TestName_p;
+
+ if (DTLSResourceTable[TnlIdx] != NULL) {
+ CRYPTO_NOTICE("tnl_idx-%d- existed, will be removed first.\n", TnlIdx);
+ mtk_ddk_remove_dtls_param(&DTLSResourceTable[TnlIdx]);
+ }
+
+ TestName_p = "Inline DTLS-CAPWAP SA setting";
+
+ if (mtk_capwap_dtls_offload(false, true, true, true, false, DTLSParam_p,
+ &DTLSResourceTable[TnlIdx]))
+ CRYPTO_INFO("%s DONE\n", TestName_p);
+ else
+ CRYPTO_ERR("%s: %s FAILED\n", __func__, TestName_p);
+}
+
+void mtk_remove_dtls_param(struct DTLS_param *DTLSParam_p, int TnlIdx)
+{
+ mtk_ddk_remove_dtls_param(&DTLSResourceTable[TnlIdx]);
+}