Merge "[qca-nss-drv] PPE Logging"
diff --git a/Makefile b/Makefile
index a89710d..4804b0d 100644
--- a/Makefile
+++ b/Makefile
@@ -84,6 +84,7 @@
 			nss_pppoe_log.o \
 			nss_pppoe_stats.o \
 			nss_pptp.o \
+			nss_pptp_log.o \
 			nss_pptp_stats.o \
 			nss_rps.o \
 			nss_qrfs.o \
@@ -141,6 +142,16 @@
 ccflags-y += -I$(obj)/nss_hal/ipq807x -DNSS_HAL_IPQ807x_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT
 endif
 
+ifeq ($(SoC),$(filter $(SoC),ipq60xx ipq60xx_64))
+qca-nss-drv-objs += nss_data_plane/nss_data_plane_edma.o \
+			nss_hal/ipq60xx/nss_hal_pvt.o \
+			nss_dtls_cmn.o \
+			nss_dtls_cmn_log.o \
+			nss_crypto_cmn.o \
+			nss_crypto_cmn_log.o
+ccflags-y += -I$(obj)/nss_hal/ipq60xx -DNSS_HAL_IPQ60XX_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT
+endif
+
 ccflags-y += -I$(obj)/nss_hal/include -I$(obj)/nss_data_plane/include -I$(obj)/exports -DNSS_DEBUG_LEVEL=0 -DNSS_PKT_STATS_ENABLED=1
 
 ccflags-y += -DNSS_PM_DEBUG_LEVEL=0 -DNSS_SKB_REUSE_SUPPORT=1
diff --git a/Makefile.fsm b/Makefile.fsm
index c4a3ad1..5acbb96 100644
--- a/Makefile.fsm
+++ b/Makefile.fsm
@@ -74,6 +74,7 @@
 			nss_pppoe_log.o \
 			nss_pppoe_stats.o \
 			nss_pptp.o \
+			nss_pptp_log.o \
 			nss_pptp_stats.o \
 			nss_rps.o \
 			nss_shaper.o \
diff --git a/exports/arch/nss_ipq60xx.h b/exports/arch/nss_ipq60xx.h
new file mode 100644
index 0000000..129bfef
--- /dev/null
+++ b/exports/arch/nss_ipq60xx.h
@@ -0,0 +1,47 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/**
+ * @file nss_ipq60xx.h
+ *	Architecture dependent parameters.
+ */
+#ifndef __NSS_IPQ60XX_H
+#define __NSS_IPQ60XX_H
+
+/**
+ * @addtogroup nss_arch_macros_ipq60xx
+ * @{
+ */
+
+#define NSS_MAX_NUM_PRI 4		/**< Maximum number of priority queues in NSS. */
+#define NSS_HOST_CORES 4		/**< Number of host cores. */
+#define NSS_PPE_SUPPORTED		/**< PPE supported flag. */
+
+#define NSS_N2H_RING_COUNT 5		/**< Number of N2H rings. */
+#define NSS_H2N_RING_COUNT 11		/**< Number of H2N rings. */
+#define NSS_RING_SIZE	128		/**< Ring size. */
+
+/*
+ * <TODO: Needs to be removed
+ */
+#define NSS_IMEM_START	0x0		/**< NSS IMEM start address. */
+#define NSS_IMEM_SIZE	0x0		/**< NSS IMEM size per core. */
+
+/**
+ * @}
+ */
+
+#endif /** __NSS_IPQ60XX_H */
diff --git a/exports/arch/nss_ipq60xx_64.h b/exports/arch/nss_ipq60xx_64.h
new file mode 100644
index 0000000..86e8ba4
--- /dev/null
+++ b/exports/arch/nss_ipq60xx_64.h
@@ -0,0 +1,47 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/**
+ * @file nss_ipq60xx_64.h
+ *	Architecture dependent parameters.
+ */
+#ifndef __NSS_IPQ60XX_64_H
+#define __NSS_IPQ60XX_64_H
+
+/**
+ * @addtogroup nss_arch_macros_ipq60xx_64
+ * @{
+ */
+
+#define NSS_MAX_NUM_PRI 4		/**< Maximum number of priority queues in NSS. */
+#define NSS_HOST_CORES 4		/**< Number of host cores. */
+#define NSS_PPE_SUPPORTED		/**< PPE supported flag. */
+
+#define NSS_N2H_RING_COUNT 5		/**< Number of N2H rings. */
+#define NSS_H2N_RING_COUNT 11		/**< Number of H2N rings. */
+#define NSS_RING_SIZE	128		/**< Ring size. */
+
+/*
+ * <TODO: Needs to be removed
+ */
+#define NSS_IMEM_START	0x0		/**< NSS IMEM start address. */
+#define NSS_IMEM_SIZE	0x0		/**< NSS IMEM size per core. */
+
+/**
+ * @}
+ */
+
+#endif /** __NSS_IPQ60XX_64_H */
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 08f2540..1ac1813 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -352,13 +352,22 @@
 extern nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm);
 
 /**
- * nss_n2h_register_sysctl
- *	Registers the N2H sysctl entry to the sysctl tree.
+ * nss_n2h_single_core_register_sysctl
+ *	Registers the N2H sysctl entry to the sysctl tree for a single-core system.
  *
  * @return
  * None.
  */
-extern void nss_n2h_register_sysctl(void);
+extern void nss_n2h_single_core_register_sysctl(void);
+
+/**
+ * nss_n2h_multi_core_register_sysctl
+ *	Registers the N2H sysctl entry to the sysctl tree for a multi-core system.
+ *
+ * @return
+ * None.
+ */
+extern void nss_n2h_multi_core_register_sysctl(void);
 
 /**
  * nss_n2h_unregister_sysctl
diff --git a/nss_core.h b/nss_core.h
index 60757db..38a4402 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -195,7 +195,7 @@
 /*
  * NSS maximum IRQ per interrupt instance/core
  */
-#if defined(NSS_HAL_IPQ807x_SUPPORT)
+#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT)
 #define NSS_MAX_IRQ_PER_INSTANCE 6
 #define NSS_MAX_IRQ_PER_CORE 9
 #else
diff --git a/nss_coredump.c b/nss_coredump.c
index ee3888b..aa4ba82 100644
--- a/nss_coredump.c
+++ b/nss_coredump.c
@@ -73,7 +73,7 @@
 	int dumped, timed;
 	int i;
 
-	for (i = 0; i < NSS_MAX_CORES; i++) {
+	for (i = 0; i < nss_top_main.num_nss; i++) {
 		struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i];
 		if (nss_ctx->state & NSS_CORE_STATE_FW_DEAD || !nss_ctx->nmap)
 			continue;
@@ -91,7 +91,7 @@
 	dumped = timed = 0;
 	do {
 		mdelay(200);
-		for (i = 0; i < NSS_MAX_CORES; i++) {
+		for (i = 0; i < nss_top_main.num_nss; i++) {
 			struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i];
 			if ((nss_ctx->state & NSS_CORE_STATE_FW_DEAD ||
 				!nss_ctx->nmap) &&
@@ -100,7 +100,7 @@
 				dumped++;
 			}
 		}
-		if (dumped >= NSS_MAX_CORES) {
+		if (dumped >= nss_top_main.num_nss) {
 			nss_warning("NSS FW dump completed\n");
 			break;
 		}
@@ -190,7 +190,7 @@
 	if (nss_own->state & NSS_CORE_STATE_PANIC)
 		return;
 
-	for (i = 0; i < NSS_MAX_CORES; i++) {
+	for (i = 0; i < nss_top_main.num_nss; i++) {
 
 		/*
 		 * only for two core now; if more cores, a counter is required
diff --git a/nss_data_plane/nss_data_plane_edma.c b/nss_data_plane/nss_data_plane_edma.c
index f8d53f6..c4067ff 100644
--- a/nss_data_plane/nss_data_plane_edma.c
+++ b/nss_data_plane/nss_data_plane_edma.c
@@ -298,7 +298,7 @@
 	 * Packets recieved on physical interface can be exceptioned to HLOS
 	 * from any NSS core so we need to register data plane for all
 	 */
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top->num_nss; core++) {
 		nss_core_register_subsys_dp(&nss_top->nss[core], if_num, nss_dp_receive, NULL, NULL, netdev, ndpp->features);
 	}
 
@@ -347,7 +347,7 @@
 {
 	int i, core;
 
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top_main.num_nss; core++) {
 		for (i = 1; i < NSS_DATA_PLANE_EDMA_MAX_INTERFACES + 1; i++) {
 			if (nss_top_main.nss[core].subsys_dp_register[i].ndev) {
 				nss_data_plane_unregister_from_nss_dp(i);
diff --git a/nss_data_plane/nss_data_plane_gmac.c b/nss_data_plane/nss_data_plane_gmac.c
index 64157d1..1345cbb 100644
--- a/nss_data_plane/nss_data_plane_gmac.c
+++ b/nss_data_plane/nss_data_plane_gmac.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -215,7 +215,7 @@
 	 * Packets recieved on physical interface can be exceptioned to HLOS
 	 * from any NSS core so we need to register data plane for all
 	 */
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top->num_nss; core++) {
 		nss_core_register_subsys_dp(&nss_top->nss[core], if_num, nss_gmac_receive, NULL, NULL, netdev, ndpp->features);
 	}
 
@@ -264,7 +264,7 @@
 {
 	int i, core;
 
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top_main.num_nss; core++) {
 		for (i = 0; i < NSS_DATA_PLANE_GMAC_MAX_INTERFACES; i++) {
 			if (nss_top_main.nss[core].subsys_dp_register[i].ndev) {
 				nss_data_plane_unregister_from_nss_gmac(i);
diff --git a/nss_gre_redir_stats.c b/nss_gre_redir_stats.c
index f94f64c..4d4f260 100644
--- a/nss_gre_redir_stats.c
+++ b/nss_gre_redir_stats.c
@@ -44,8 +44,8 @@
 	"Split SG alloc fail",
 	"Split linear copy fail",
 	"Split not enough tailroom",
-	"Decap eapol frames",
 	"exception ds invalid dst"
+	"Decap eapol frames",
 };
 
 /*
diff --git a/nss_hal/include/nss_hal.h b/nss_hal/include/nss_hal.h
index e16f975..52ed690 100644
--- a/nss_hal/include/nss_hal.h
+++ b/nss_hal/include/nss_hal.h
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -40,6 +40,9 @@
 #if defined(NSS_HAL_IPQ807x_SUPPORT)
 extern struct nss_hal_ops nss_hal_ipq807x_ops;
 #endif
+#if defined(NSS_HAL_IPQ60XX_SUPPORT)
+extern struct nss_hal_ops nss_hal_ipq60xx_ops;
+#endif
 #if defined(NSS_HAL_FSM9010_SUPPORT)
 extern struct nss_hal_ops nss_hal_fsm9010_ops;
 #endif
diff --git a/nss_hal/ipq60xx/nss_hal_pvt.c b/nss_hal/ipq60xx/nss_hal_pvt.c
new file mode 100644
index 0000000..9a1347e
--- /dev/null
+++ b/nss_hal/ipq60xx/nss_hal_pvt.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * nss_hal_pvt.c
+ *	NSS HAL private APIs.
+ */
+
+#include <linux/err.h>
+#include <linux/version.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include "nss_hal.h"
+#include "nss_core.h"
+
+#define NSS_QGIC_IPC_REG_OFFSET 0x8
+
+#define NSS0_H2N_INTR_BASE 13
+
+/*
+ * Common CLKs
+ */
+#define NSS_NOC_CLK "nss-noc-clk"
+#define NSS_PTP_REF_CLK "nss-ptp-ref-clk"
+#define NSS_CSR_CLK "nss-csr-clk"
+#define NSS_CFG_CLK "nss-cfg-clk"
+#define NSS_NSSNOC_QOSGEN_REF_CLK "nss-nssnoc-qosgen-ref-clk"
+#define NSS_MEM_NOC_NSS_AXI_CLK "nss-mem-noc-nss-axi-clk"
+#define NSS_NSSNOC_SNOC_CLK "nss-nssnoc-snoc-clk"
+#define NSS_NSSNOC_TIMEOUT_REF_CLK "nss-nssnoc-timeout-ref-clk"
+#define NSS_CE_AXI_CLK "nss-ce-axi-clk"
+#define NSS_CE_APB_CLK "nss-ce-apb-clk"
+#define NSS_NSSNOC_CE_AXI_CLK "nss-nssnoc-ce-axi-clk"
+#define NSS_NSSNOC_CE_APB_CLK "nss-nssnoc-ce-apb-clk"
+
+/*
+ * Per-core CLKS
+ */
+#define NSS_NSSNOC_AHB_CLK "nss-nssnoc-ahb-clk"
+#define NSS_CORE_CLK "nss-core-clk"
+#define NSS_AHB_CLK "nss-ahb-clk"
+#define NSS_AXI_CLK "nss-axi-clk"
+#define NSS_NC_AXI_CLK "nss-nc-axi-clk"
+
+/*
+ * Voltage values
+ */
+#define NOMINAL_VOLTAGE 1
+#define TURBO_VOLTAGE 2
+
+/*
+ * Core reset part 1
+ */
+#define NSS_CORE_GCC_RESET_1 0x00000020
+
+/*
+ * Core reset part 2
+ */
+#define NSS_CORE_GCC_RESET_2 0x00000017
+
+/*
+ * Voltage regulator
+ */
+struct regulator *npu_reg;
+
+/*
+ * GCC reset
+ */
+void __iomem *nss_misc_reset;
+void __iomem *nss_misc_reset_flag;
+void __iomem *nss_misc_reset_addr;
+
+/*
+ * Purpose of each interrupt index: This should match the order defined in the NSS firmware
+ */
+enum nss_hal_n2h_intr_purpose {
+	NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS = 0,
+	NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE = 1,
+	NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED = 2,
+	NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0 = 3,
+	NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1 = 4,
+	NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2 = 5,
+	NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3 = 6,
+	NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE = 7,
+	NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS = 8,
+	NSS_HAL_N2H_INTR_PURPOSE_MAX = 9,
+};
+
+/*
+ * Interrupt type to cause vector.
+ */
+static uint32_t intr_cause[NSS_MAX_CORES][NSS_H2N_INTR_TYPE_MAX] = {
+				/* core0 */
+				{(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE)),
+				(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_DATA_COMMAND_QUEUE)),
+				(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TX_UNBLOCKED)),
+				(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TRIGGER_COREDUMP)),
+				(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE))}
+};
+
+/*
+ * nss_hal_wq_function()
+ *	Added to Handle BH requests to kernel
+ */
+void nss_hal_wq_function(struct work_struct *work)
+{
+	kfree((void *)work);
+}
+
+/*
+ * nss_hal_handle_irq()
+ */
+static irqreturn_t nss_hal_handle_irq(int irq, void *ctx)
+{
+	struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx;
+
+	disable_irq_nosync(irq);
+	napi_schedule(&int_ctx->napi);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * __nss_hal_of_get_pdata()
+ *	Retrieve platform data from device node.
+ */
+static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev)
+{
+	struct device_node *np = of_node_get(pdev->dev.of_node);
+	struct nss_platform_data *npd;
+	struct nss_ctx_instance *nss_ctx = NULL;
+	struct nss_top_instance *nss_top = &nss_top_main;
+	struct resource res_nphys, res_qgic_phys;
+	int32_t i;
+
+	npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL);
+	if (!npd) {
+		return NULL;
+	}
+
+	if (of_property_read_u32(np, "qcom,id", &npd->id)
+	    || of_property_read_u32(np, "qcom,load-addr", &npd->load_addr)
+	    || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue)
+	    || of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) {
+		pr_err("%s: error reading critical device node properties\n", np->name);
+		goto out;
+	}
+
+	/*
+	 * Read frequencies. If failure, load default values.
+	 */
+	of_property_read_u32(np, "qcom,low-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency);
+	of_property_read_u32(np, "qcom,mid-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency);
+	of_property_read_u32(np, "qcom,max-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency);
+
+	if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) {
+		pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name);
+		goto out;
+	}
+
+	nss_ctx = &nss_top->nss[npd->id];
+	nss_ctx->id = npd->id;
+
+	if (of_address_to_resource(np, 0, &res_nphys) != 0) {
+		nss_info_always("%p: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id);
+		goto out;
+	}
+
+	if (of_address_to_resource(np, 1, &res_qgic_phys) != 0) {
+		nss_info_always("%p: nss%d: of_address_to_resource() fail for qgic_phys\n", nss_ctx, nss_ctx->id);
+		goto out;
+	}
+
+	/*
+	 * Save physical addresses
+	 */
+	npd->nphys = res_nphys.start;
+	npd->qgic_phys = res_qgic_phys.start;
+
+	npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys));
+	if (!npd->nmap) {
+		nss_info_always("%p: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id);
+		goto out;
+	}
+
+	npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys));
+	if (!npd->qgic_map) {
+		nss_info_always("%p: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id);
+		goto out;
+	}
+
+	NSS_CORE_DSB();
+
+	/*
+	 * Get IRQ numbers
+	 */
+	for (i = 0 ; i < npd->num_irq; i++) {
+		npd->irq[i] = irq_of_parse_and_map(np, i);
+		if (!npd->irq[i]) {
+			nss_info_always("%p: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i);
+			goto out;
+		}
+	}
+
+	nss_hal_dt_parse_features(np, npd);
+
+	of_node_put(np);
+	return npd;
+
+out:
+	if (npd->nmap) {
+		iounmap(npd->nmap);
+	}
+
+	if (npd->vmap) {
+		iounmap(npd->vmap);
+	}
+
+	devm_kfree(&pdev->dev, npd);
+	of_node_put(np);
+	return NULL;
+}
+
+/*
+ * __nss_hal_core_reset()
+ */
+static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src)
+{
+	/*
+	 * De-assert reset for first set
+	 */
+	nss_write_32(nss_misc_reset, 0x0, 0x0);
+
+	/*
+	 * Minimum 10 - 20 cycles delay is required after
+	 * de-asserting NSS reset clamp
+	 */
+	usleep_range(10, 20);
+
+	/*
+	 * Load instruction to NSS UTCM
+	 * TODO: Can uncomment uTCM later for booting.
+	 */
+	//nss_write_32(nss_misc_reset_addr, 0, 0xD6E00000);
+	nss_write_32(nss_misc_reset_addr, 0x400, 0xD6E00000);
+
+	/*
+	 * Release NSS from Reset
+	 */
+	nss_write_32(map, 0x4, 0x1);
+
+	/*
+	 * NSS code location
+	 * TODO: Can unncomment to support UTCM
+	 */
+	//nss_write_32(map, 0, 0x3e000000);
+	nss_write_32(map, 0x10, addr);
+
+	/*
+	 * Program address configuration
+	 */
+	nss_write_32(map, 0xc, 0x1);
+	nss_write_32(map, 0x8, 0x3C000000);
+	nss_write_32(map, 0x4, 0x0);
+
+	/*
+	 * Clear flag between A53 and NSS for print
+	 */
+	nss_write_32(nss_misc_reset_flag, 0, 0x0);
+
+	return 0;
+}
+
+/*
+ * __nss_hal_debug_enable()
+ *	Enable NSS debug
+ */
+static void __nss_hal_debug_enable(void)
+{
+
+}
+
+/*
+ * nss_hal_clock_set_and_enable()
+ */
+static int nss_hal_clock_set_and_enable(struct device *dev, const char *id, unsigned long rate)
+{
+	struct clk *nss_clk = NULL;
+	int err;
+
+	nss_clk = devm_clk_get(dev, id);
+	if (IS_ERR(nss_clk)) {
+		pr_err("%p: cannot get clock: %s\n", dev, id);
+		return -EFAULT;
+	}
+
+	if (rate) {
+		err = clk_set_rate(nss_clk, rate);
+		if (err) {
+			pr_err("%p: cannot set %s freq\n", dev, id);
+			return -EFAULT;
+		}
+	}
+
+	err = clk_prepare_enable(nss_clk);
+	if (err) {
+		pr_err("%p: cannot enable clock: %s\n", dev, id);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * __nss_hal_common_reset
+ *	Do reset/clock configuration common to all cores
+ */
+static int __nss_hal_common_reset(struct platform_device *nss_dev)
+{
+
+	struct device_node *cmn = NULL;
+	struct resource res_nss_misc_reset;
+	struct resource res_nss_misc_reset_flag;
+	struct resource res_nss_misc_reset_addr;
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NOC_CLK, 461500000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_PTP_REF_CLK, 150000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CSR_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CFG_CLK, 100000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_QOSGEN_REF_CLK, 19200000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_MEM_NOC_NSS_AXI_CLK, 461500000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_SNOC_CLK, 266600000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_TIMEOUT_REF_CLK, 4800000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_AXI_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_APB_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_AXI_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_APB_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	/*
+	 * Get reference to NSS common device node
+	 */
+	cmn = of_find_node_by_name(NULL, "nss-common");
+	if (!cmn) {
+		pr_err("%p: Unable to find nss-common node\n", nss_dev);
+		return -EFAULT;
+	}
+
+	if (of_address_to_resource(cmn, 0, &res_nss_misc_reset) != 0) {
+		pr_err("%p: of_address_to_resource() return error for nss_misc_reset\n", nss_dev);
+		of_node_put(cmn);
+		return -EFAULT;
+	}
+
+	if (of_address_to_resource(cmn, 1, &res_nss_misc_reset_flag) != 0) {
+		pr_err("%p: of_address_to_resource() return error for nss_misc_reset_flag\n", nss_dev);
+		of_node_put(cmn);
+		return -EFAULT;
+	}
+
+	if (of_address_to_resource(cmn, 2, &res_nss_misc_reset_addr) != 0) {
+		pr_err("%p: of_address_to_resource() return error for nss_misc_reset_addr\n", nss_dev);
+		of_node_put(cmn);
+		return -EFAULT;
+	}
+
+	of_node_put(cmn);
+
+	nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset));
+	if (!nss_misc_reset) {
+		pr_err("%p: ioremap fail for nss_misc_reset\n", nss_dev);
+		return -EFAULT;
+	}
+
+	nss_misc_reset_flag = ioremap_nocache(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag));
+	if (!nss_misc_reset_flag) {
+		pr_err("%p: ioremap fail for nss_misc_reset_flag\n", nss_dev);
+		return -EFAULT;
+	}
+
+	nss_misc_reset_addr = ioremap_nocache(res_nss_misc_reset_addr.start, resource_size(&res_nss_misc_reset_addr));
+	if (!nss_misc_reset_addr) {
+		pr_err("%p: ioremap fail for nss_misc_reset_addr\n", nss_dev);
+		return -EFAULT;
+	}
+
+	nss_top_main.nss_hal_common_init_done = true;
+	nss_info("nss_hal_common_reset Done\n");
+
+	return 0;
+}
+
+/*
+ * __nss_hal_clock_configure()
+ */
+static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd)
+{
+	int i;
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AHB_CLK, 200000000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AXI_CLK, 461500000)) {
+		return -EFAULT;
+	}
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NC_AXI_CLK, 461500000)) {
+		return -EFAULT;
+	}
+
+	/*
+	 * No entries, then just load default
+	 */
+	if ((nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency == 0) ||
+		(nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency == 0) ||
+		(nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency == 0)) {
+		nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_187;
+		nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_748;
+		nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_1497;
+		nss_info_always("Running default frequencies\n");
+	}
+
+	/*
+	 * Test frequency from dtsi, if fail, try to set default frequency.
+	 */
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency)) {
+		if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, NSS_FREQ_1497)) {
+			return -EFAULT;
+		}
+	}
+
+	/*
+	 * Setup ranges, test frequency, and display.
+	 */
+	for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) {
+		if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) {
+			nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_187_MIN;
+			nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_187_MAX;
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) {
+			nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_748_MIN;
+			nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_748_MAX;
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) {
+			nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1497_MIN;
+			nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1497_MAX;
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) {
+			nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1689_MIN;
+			nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1689_MAX;
+		} else {
+			nss_info_always("Frequency not found %d\n", nss_runtime_samples.freq_scale[i].frequency);
+			return -EFAULT;
+		}
+
+		/*
+		 * Test the frequency, if fail, then default to safe frequency and abort
+		 */
+		if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[i].frequency)) {
+			return -EFAULT;
+		}
+	}
+
+	nss_info_always("Supported Frequencies - ");
+	for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) {
+		if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) {
+			nss_info_always("187.2 MHz ");
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) {
+			nss_info_always("748.8 MHz ");
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) {
+			nss_info_always("1.4976 GHz ");
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) {
+			nss_info_always("1.6896 GHz ");
+		} else {
+			nss_info_always("Error\nNo Table/Invalid Frequency Found\n");
+			return -EFAULT;
+		}
+	}
+	nss_info_always("\n");
+
+	/*
+	 * Set values only once for core0. Grab the proper clock.
+	 */
+	nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK);
+
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) {
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * __nss_hal_read_interrupt_cause()
+ */
+static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause)
+{
+}
+
+/*
+ * __nss_hal_clear_interrupt_cause()
+ */
+static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause)
+{
+}
+
+/*
+ * __nss_hal_disable_interrupt()
+ */
+static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause)
+{
+}
+
+/*
+ * __nss_hal_enable_interrupt()
+ */
+static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause)
+{
+}
+
+/*
+ * __nss_hal_send_interrupt()
+ */
+static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type)
+{
+	/*
+	 * Check if core and type is Valid
+	 */
+	nss_assert(nss_ctx->id < nss_top_main.num_nss);
+	nss_assert(type < NSS_H2N_INTR_TYPE_MAX);
+
+	nss_write_32(nss_ctx->qgic_map, NSS_QGIC_IPC_REG_OFFSET, intr_cause[nss_ctx->id][type]);
+}
+
+/*
+ * __nss_hal_request_irq()
+ */
+static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num)
+{
+	struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num];
+	int err = -1, irq = npd->irq[irq_num];
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) {
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+		int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS;
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) {
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT);
+		int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE;
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) {
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT);
+		int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED;
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) {
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+		int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0;
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) {
+		int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1;
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) {
+		int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2;
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) {
+		int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3;
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) {
+		int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE;
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT);
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx);
+	}
+
+	if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) {
+		netif_napi_add(int_ctx->ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT);
+		int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS;
+		err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx);
+	}
+
+	if (err) {
+		return err;
+	}
+
+	int_ctx->irq = irq;
+	return 0;
+}
+
+/*
+ * nss_hal_ipq60xx_ops
+ */
+struct nss_hal_ops nss_hal_ipq60xx_ops = {
+	.common_reset = __nss_hal_common_reset,
+	.core_reset = __nss_hal_core_reset,
+	.clock_configure = __nss_hal_clock_configure,
+	.firmware_load = nss_hal_firmware_load,
+	.debug_enable = __nss_hal_debug_enable,
+	.of_get_pdata = __nss_hal_of_get_pdata,
+	.request_irq = __nss_hal_request_irq,
+	.send_interrupt = __nss_hal_send_interrupt,
+	.enable_interrupt = __nss_hal_enable_interrupt,
+	.disable_interrupt = __nss_hal_disable_interrupt,
+	.clear_interrupt_cause = __nss_hal_clear_interrupt_cause,
+	.read_interrupt_cause = __nss_hal_read_interrupt_cause,
+};
diff --git a/nss_hal/ipq807x/nss_hal_pvt.c b/nss_hal/ipq807x/nss_hal_pvt.c
index e4646b0..b8fc449 100644
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -637,7 +637,7 @@
 	/*
 	 * Check if core and type is Valid
 	 */
-	nss_assert(nss_ctx->id < NSS_MAX_CORES);
+	nss_assert(nss_ctx->id < nss_top_main.num_nss);
 	nss_assert(type < NSS_H2N_INTR_TYPE_MAX);
 
 	nss_write_32(nss_ctx->qgic_map, NSS_QGIC_IPC_REG_OFFSET, intr_cause[nss_ctx->id][type]);
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index 88ff1a1..6f191ef 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -399,7 +399,7 @@
 	 */
 	if (npd->crypto_enabled == NSS_FEATURE_ENABLED) {
 		nss_top->crypto_handler_id = nss_dev->id;
-#if defined(NSS_HAL_IPQ807x_SUPPORT)
+#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT)
 		nss_crypto_cmn_register_handler();
 #else
 		nss_top->crypto_enabled = 1;
@@ -442,7 +442,7 @@
 
 	if (npd->dtls_enabled == NSS_FEATURE_ENABLED) {
 		nss_top->dtls_handler_id = nss_dev->id;
-#if defined(NSS_HAL_IPQ807x_SUPPORT)
+#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT)
 		nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER] = nss_dev->id;
 		nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER] = nss_dev->id;
 		nss_dtls_cmn_register_handler();
@@ -572,11 +572,6 @@
 	}
 
 	/*
-	 * Increment number of cores
-	 */
-	nss_top->num_nss++;
-
-	/*
 	 * Enable interrupts for NSS core
 	 */
 	nss_hal_enable_interrupt(nss_ctx, nss_ctx->int_ctx[0].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
diff --git a/nss_init.c b/nss_init.c
index 380a1bd..e0393bc 100644
--- a/nss_init.c
+++ b/nss_init.c
@@ -658,18 +658,28 @@
 	if (of_machine_is_compatible("qcom,ipq8064") || of_machine_is_compatible("qcom,ipq8062")) {
 		nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
 		nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
+		nss_top_main.num_nss = 2;
 	}
 #endif
 #if defined(NSS_HAL_IPQ807x_SUPPORT)
 	if (of_machine_is_compatible("qcom,ipq807x")) {
 		nss_top_main.hal_ops = &nss_hal_ipq807x_ops;
 		nss_top_main.data_plane_ops = &nss_data_plane_edma_ops;
+		nss_top_main.num_nss = 2;
+	}
+#endif
+#if defined(NSS_HAL_IPQ60XX_SUPPORT)
+	if (of_machine_is_compatible("qcom,ipq6018")) {
+		nss_top_main.hal_ops = &nss_hal_ipq60xx_ops;
+		nss_top_main.data_plane_ops = &nss_data_plane_edma_ops;
+		nss_top_main.num_nss = 1;
 	}
 #endif
 #if defined(NSS_HAL_FSM9010_SUPPORT)
 	if (of_machine_is_compatible("qcom,fsm9010")) {
 		nss_top_main.hal_ops = &nss_hal_fsm9010_ops;
 		nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
+		nss_top_main.num_nss = 1;
 	}
 #endif
 	if (!nss_top_main.hal_ops) {
@@ -682,6 +692,7 @@
 	 */
 	nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
 	nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
+	nss_top_main.num_nss = 2;
 
 #endif /* NSS_DT_SUPPORT */
 	nss_top_main.nss_hal_common_init_done = false;
@@ -720,7 +731,11 @@
 	/*
 	 * Registering sysctl for n2h specific config.
 	 */
-	nss_n2h_register_sysctl();
+	if (nss_top_main.num_nss == 1) {
+		nss_n2h_single_core_register_sysctl();
+	} else {
+		nss_n2h_multi_core_register_sysctl();
+	}
 
 	/*
 	 * Registering sysctl for rps specific config.
@@ -801,7 +816,7 @@
 	/*
 	 * INIT ppe on supported platform
 	 */
-	if (of_machine_is_compatible("qcom,ipq807x")) {
+	if (of_machine_is_compatible("qcom,ipq807x") || of_machine_is_compatible("qcom,ipq6018")) {
 		nss_ppe_init();
 	}
 
@@ -855,7 +870,7 @@
 	/*
 	 * cleanup ppe on supported platform
 	 */
-	if (of_machine_is_compatible("qcom,ipq807x")) {
+	if (of_machine_is_compatible("qcom,ipq807x") || of_machine_is_compatible("qcom,ipq6018")) {
 		nss_ppe_free();
 	}
 
diff --git a/nss_ipsec.c b/nss_ipsec.c
index 65b7085..4b44f50 100644
--- a/nss_ipsec.c
+++ b/nss_ipsec.c
@@ -39,6 +39,11 @@
 #define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
 #define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
 
+#elif defined(NSS_HAL_IPQ60XX_SUPPORT)
+#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+
 #else
 #define NSS_IPSEC_ENCAP_INTERFACE_NUM -1
 #define NSS_IPSEC_DECAP_INTERFACE_NUM -1
diff --git a/nss_log.c b/nss_log.c
index 7a0fdd5..aee96ec 100644
--- a/nss_log.c
+++ b/nss_log.c
@@ -96,7 +96,7 @@
 	 * i_private is passed to us by debug_fs_create()
 	 */
 	nss_id = (int)(nss_ptr_t)inode->i_private;
-	if (nss_id < 0 || nss_id >= NSS_MAX_CORES) {
+	if (nss_id < 0 || nss_id >= nss_top_main.num_nss) {
 		nss_warning("nss_id is not valid :%d\n", nss_id);
 		return -ENODEV;
 	}
@@ -399,7 +399,7 @@
 	void *addr = NULL;
 	nss_tx_status_t status;
 
-	if (nss_id >= NSS_MAX_CORES) {
+	if (nss_id >= nss_top_main.num_nss) {
 		return false;
 	}
 
@@ -541,7 +541,7 @@
 		return ret;
 	}
 
-	for (i = 0; i < NSS_MAX_CORES; i++) {
+	for (i = 0; i < nss_top_main.num_nss; i++) {
 		/*
 		 * Register the callback handler and allocate the debug log buffers
 		 */
@@ -581,7 +581,7 @@
 		return;
 	}
 
-	for (i = 0; i < NSS_MAX_CORES; i++) {
+	for (i = 0; i < nss_top_main.num_nss; i++) {
 		char file[10];
 		extern struct file_operations nss_logs_core_ops;
 
diff --git a/nss_meminfo.c b/nss_meminfo.c
index 1a0d36f..44e98d2 100644
--- a/nss_meminfo.c
+++ b/nss_meminfo.c
@@ -517,7 +517,7 @@
 	 * i_private is passed to us by debug_fs_create()
 	 */
 	nss_id = (int)(nss_ptr_t)seq->private;
-	if (nss_id < 0 || nss_id >= NSS_MAX_CORES) {
+	if (nss_id < 0 || nss_id >= nss_top_main.num_nss) {
 		nss_warning("nss_id: %d is not valid\n", nss_id);
 		return -ENODEV;
 	}
@@ -598,7 +598,7 @@
 		return;
 	}
 
-	for (i = 0; i < NSS_MAX_CORES; i++) {
+	for (i = 0; i < nss_top_main.num_nss; i++) {
 		char file[10];
 		snprintf(file, sizeof(file), "core%d", i);
 		meminfo_core_dentries[i] = debugfs_create_file(file, 0400, meminfo_main_dentry,
diff --git a/nss_n2h.c b/nss_n2h.c
index 463f924..60320b0 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -1493,7 +1493,82 @@
 			NSS_CORE_1);
 }
 
-static struct ctl_table nss_n2h_table[] = {
+static struct ctl_table nss_n2h_table_single_core[] = {
+	{
+		.procname	= "n2h_empty_pool_buf_core0",
+		.data		= &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_empty_pool_buf_cfg_core0_handler,
+	},
+	{
+		.procname	= "n2h_empty_paged_pool_buf_core0",
+		.data		= &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
+	},
+	{
+		.procname	= "n2h_low_water_core0",
+		.data		= &nss_n2h_water_mark[NSS_CORE_0][0],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_water_mark_core0_handler,
+	},
+	{
+		.procname	= "n2h_high_water_core0",
+		.data		= &nss_n2h_water_mark[NSS_CORE_0][1],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_water_mark_core0_handler,
+	},
+	{
+		.procname	= "n2h_paged_low_water_core0",
+		.data		= &nss_n2h_paged_water_mark[NSS_CORE_0][0],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_paged_water_mark_core0_handler,
+	},
+	{
+		.procname	= "n2h_paged_high_water_core0",
+		.data		= &nss_n2h_paged_water_mark[NSS_CORE_0][1],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_paged_water_mark_core0_handler,
+	},
+	{
+		.procname	= "n2h_wifi_pool_buf",
+		.data		= &nss_n2h_wifi_pool_buf_cfg,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_wifi_payloads_handler,
+	},
+	{
+		.procname	= "mitigation_core0",
+		.data		= &nss_n2h_core0_mitigation_cfg,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_mitigationcfg_core0_handler,
+	},
+	{
+		.procname	= "extra_pbuf_core0",
+		.data		= &nss_n2h_core0_add_buf_pool_size,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_buf_cfg_core0_handler,
+	},
+	{
+		.procname	= "n2h_queue_limit_core0",
+		.data		= &nss_n2h_queue_limit[NSS_CORE_0],
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &nss_n2h_queue_limit_core0_handler,
+	},
+
+	{ }
+};
+
+static struct ctl_table nss_n2h_table_multi_core[] = {
 	{
 		.procname	= "n2h_empty_pool_buf_core0",
 		.data		= &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
@@ -1632,11 +1707,14 @@
 	{ }
 };
 
+/*
+ * This table will be overwritten during single-core registration
+ */
 static struct ctl_table nss_n2h_dir[] = {
 	{
 		.procname		= "n2hcfg",
 		.mode			= 0555,
-		.child			= nss_n2h_table,
+		.child			= nss_n2h_table_multi_core,
 	},
 	{ }
 };
@@ -1737,7 +1815,7 @@
  */
 struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
 {
-	if (core >= NSS_MAX_CORES) {
+	if (core >= nss_top_main.num_nss) {
 		nss_warning("Input core number %d is wrong \n", core);
 		return NULL;
 	}
@@ -1764,9 +1842,71 @@
 }
 
 /*
- * nss_n2h_register_sysctl()
+ * nss_n2h_single_core_register_sysctl()
  */
-void nss_n2h_register_sysctl(void)
+void nss_n2h_single_core_register_sysctl(void)
+{
+	/*
+	 * RPS sema init
+	 */
+	sema_init(&nss_n2h_rcp.sem, 1);
+	init_completion(&nss_n2h_rcp.complete);
+
+	/*
+	 * MITIGATION sema init for core0
+	 */
+	sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
+	init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
+
+	/*
+	 * PBUF addition sema init for core0
+	 */
+	sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
+	init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
+
+	/*
+	 * Core0
+	 */
+	sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
+	init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
+		nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
+		nss_n2h_water_mark[NSS_CORE_0][0];
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
+		nss_n2h_water_mark[NSS_CORE_0][1];
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
+		nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
+		nss_n2h_paged_water_mark[NSS_CORE_0][0];
+	nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
+		nss_n2h_paged_water_mark[NSS_CORE_0][1];
+
+	/*
+	 * WiFi pool buf cfg sema init
+	 */
+	sema_init(&nss_n2h_wp.sem, 1);
+	init_completion(&nss_n2h_wp.complete);
+
+	/*
+	 * N2H queue config sema init
+	 */
+	sema_init(&nss_n2h_q_lim_pvt.sem, 1);
+	init_completion(&nss_n2h_q_lim_pvt.complete);
+
+	nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
+
+	/*
+	 * Register sysctl table.
+	 */
+	nss_n2h_dir[0].child = nss_n2h_table_single_core;
+	nss_n2h_header = register_sysctl_table(nss_n2h_root);
+}
+
+/*
+ * nss_n2h_multi_core_register_sysctl()
+ */
+void nss_n2h_multi_core_register_sysctl(void)
 {
 	/*
 	 * RPS sema init
diff --git a/nss_n2h_stats.c b/nss_n2h_stats.c
index b188c14..f4c2a86 100644
--- a/nss_n2h_stats.c
+++ b/nss_n2h_stats.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -92,7 +92,7 @@
 	/*
 	 * N2H node stats
 	 */
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top_main.num_nss; core++) {
 		size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h core %d stats:\n\n", core);
 		spin_lock_bh(&nss_top_main.stats_lock);
 		for (i = 0; i < NSS_N2H_STATS_MAX; i++) {
diff --git a/nss_pptp.c b/nss_pptp.c
index da524a2..5f0283c 100644
--- a/nss_pptp.c
+++ b/nss_pptp.c
@@ -17,6 +17,7 @@
 #include <net/sock.h>
 #include "nss_tx_rx_common.h"
 #include "nss_pptp_stats.h"
+#include "nss_pptp_log.h"
 
 #define NSS_PPTP_TX_TIMEOUT 3000 /* 3 Seconds */
 
@@ -174,6 +175,11 @@
 	BUG_ON(!nss_pptp_verify_if_num(ncm->interface));
 
 	/*
+	 * Trace Messages
+	 */
+	nss_pptp_log_rx_msg(ntm);
+
+	/*
 	 * Is this a valid request/response packet?
 	 */
 	if (ncm->type >= NSS_PPTP_MSG_MAX) {
@@ -243,6 +249,11 @@
 	struct nss_cmn_msg *ncm = &msg->cm;
 
 	/*
+	 * Trace Messages
+	 */
+	nss_pptp_log_tx_msg(msg);
+
+	/*
 	 * Sanity check the message
 	 */
 	if (!nss_is_dynamic_interface(ncm->interface)) {
diff --git a/nss_pptp_log.c b/nss_pptp_log.c
new file mode 100644
index 0000000..8abc38e
--- /dev/null
+++ b/nss_pptp_log.c
@@ -0,0 +1,129 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_pptp_log.c
+ *	NSS PPTP logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_pptp_log_message_types_str
+ *	NSS PPTP message strings
+ */
+static int8_t *nss_pptp_log_message_types_str[NSS_PPTP_MSG_MAX] __maybe_unused = {
+	"PPTP Session Configure",
+	"PPTP Session Deconfigure",
+	"PPTP Stats",
+};
+
+/*
+ * nss_pptp_log_configure_msg()
+ *	Log NSS PPTP Session Configure.
+ */
+static void nss_pptp_log_configure_msg(struct nss_pptp_msg *npm)
+{
+	struct nss_pptp_session_configure_msg *npcm __maybe_unused = &npm->msg.session_configure_msg;
+	nss_trace("%p: NSS PPTP Session Configure message\n"
+		"PPTP Source Call ID: %x\n"
+		"PPTP Destination Call ID: %x\n"
+		"PPTP Source IP: %pI4\n"
+		"PPTP Destination IP: %pI4\n",
+		npcm, npcm->src_call_id,
+		npcm->dst_call_id, &npcm->sip,
+		&npcm->dip);
+}
+
+/*
+ * nss_pptp_log_deconfigure_msg()
+ *	Log NSS PPTP Session Deconfigure.
+ */
+static void nss_pptp_log_deconfigure_msg(struct nss_pptp_msg *npm)
+{
+	struct nss_pptp_session_deconfigure_msg *npdm __maybe_unused = &npm->msg.session_deconfigure_msg;
+	nss_trace("%p: NSS PPTP Session Configure message \n"
+		"PPTP Source Call ID: %x\n",
+		npdm, npdm->src_call_id);
+}
+
+/*
+ * nss_pptp_log_verbose()
+ *	Log message contents.
+ */
+static void nss_pptp_log_verbose(struct nss_pptp_msg *npm)
+{
+	switch (npm->cm.type) {
+	case NSS_PPTP_MSG_SESSION_CONFIGURE:
+		nss_pptp_log_configure_msg(npm);
+		break;
+
+	case NSS_PPTP_MSG_SESSION_DECONFIGURE:
+		nss_pptp_log_deconfigure_msg(npm);
+		break;
+
+	case NSS_PPTP_MSG_SYNC_STATS:
+		/*
+		 * No log for valid stats message.
+		 */
+		break;
+
+	default:
+		nss_trace("%p: Invalid message type\n", npm);
+		break;
+	}
+}
+
+/*
+ * nss_pptp_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_pptp_log_tx_msg(struct nss_pptp_msg *npm)
+{
+	if (npm->cm.type >= NSS_PPTP_MSG_MAX) {
+		nss_warning("%p: Invalid message type\n", npm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", npm, npm->cm.type, nss_pptp_log_message_types_str[npm->cm.type]);
+	nss_pptp_log_verbose(npm);
+}
+
+/*
+ * nss_pptp_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_pptp_log_rx_msg(struct nss_pptp_msg *npm)
+{
+	if (npm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", npm);
+		return;
+	}
+
+	if (npm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", npm, npm->cm.type,
+			nss_pptp_log_message_types_str[npm->cm.type],
+			npm->cm.response, nss_cmn_response_str[npm->cm.response]);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s\n",
+		npm, npm->cm.type, nss_pptp_log_message_types_str[npm->cm.type],
+		npm->cm.response, nss_cmn_response_str[npm->cm.response]);
+
+verbose:
+	nss_pptp_log_verbose(npm);
+}
diff --git a/nss_pptp_log.h b/nss_pptp_log.h
new file mode 100644
index 0000000..bb800d5
--- /dev/null
+++ b/nss_pptp_log.h
@@ -0,0 +1,41 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_PPTP_LOG_H
+#define __NSS_PPTP_LOG_H
+
+/*
+ * nss_pptp.h
+ *	NSS PPTP header file.
+ */
+
+/*
+ * Logger APIs
+ */
+
+/*
+ * nss_pptp_log_tx_msg
+ *	Logs a pptp message that is sent to the NSS firmware.
+ */
+void nss_pptp_log_tx_msg(struct nss_pptp_msg *ntm);
+
+/*
+ * nss_pptp_log_rx_msg
+ *	Logs a pptp message that is received from the NSS firmware.
+ */
+void nss_pptp_log_rx_msg(struct nss_pptp_msg *ntm);
+
+#endif /* __NSS_PPTP_LOG_H */
diff --git a/nss_project.c b/nss_project.c
index a9a2348..8703d31 100644
--- a/nss_project.c
+++ b/nss_project.c
@@ -255,7 +255,7 @@
 	 * If a value was written, send a message containing that value to each
 	 * NSS core.
 	 */
-	for (i = 0; i < NSS_MAX_CORES; ++i) {
+	for (i = 0; i < nss_top_main.num_nss; ++i) {
 		nss_project_wt_stats_send_enable(&(nss_top_main.nss[i]),
 			nss_project_wt_stats_enable);
 	}
diff --git a/nss_qrfs_stats.c b/nss_qrfs_stats.c
index 1e5734f..0dbb120 100644
--- a/nss_qrfs_stats.c
+++ b/nss_qrfs_stats.c
@@ -79,7 +79,7 @@
 	/*
 	 * QRFS statistics
 	 */
-	for (core = 0; core < NSS_MAX_CORES; core++) {
+	for (core = 0; core < nss_top_main.num_nss; core++) {
 		size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nqrfs core %d stats:\n\n", core);
 		spin_lock_bh(&nss_qrfs_stats_lock);
 		for (i = 0; i < NSS_QRFS_STATS_MAX; i++) {
diff --git a/nss_stats.c b/nss_stats.c
index 71fca9d..c02f001 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -440,7 +440,7 @@
 		return;
 	}
 
-	for (i = 0; i < NSS_MAX_CORES; ++i) {
+	for (i = 0; i < nss_top_main.num_nss; ++i) {
 		memset(file_name, 0, sizeof(file_name));
 		scnprintf(file_name, sizeof(file_name), "core%d", i);
 		core_dentry = debugfs_create_dir(file_name,