Merge "[qca-nss-drv] Added support to set nexthop"
diff --git a/Makefile b/Makefile
index 66c8c5b..53718a1 100644
--- a/Makefile
+++ b/Makefile
@@ -118,7 +118,8 @@
 			nss_hal/ipq807x/nss_hal_pvt.o \
 			nss_dtls_cmn.o \
 			nss_dtls_cmn_log.o \
-			nss_crypto_cmn.o
+			nss_crypto_cmn.o \
+			nss_crypto_cmn_log.o
 ccflags-y += -I$(obj)/nss_hal/ipq807x -DNSS_HAL_IPQ807x_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT
 endif
 
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index 21bf200..3a23af6 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -52,10 +52,10 @@
 	NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_2,
 	NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE,
 	NSS_DYNAMIC_INTERFACE_TYPE_VLAN,
-	NSS_DYNAMIC_INTERFACE_TYPE_GRE,
-	NSS_DYNAMIC_INTERFACE_TYPE_WIFILI,
 	NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_3,
+	NSS_DYNAMIC_INTERFACE_TYPE_WIFILI,
 	NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_4,
+	NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_5,
 	NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER,
 	NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_OUTER,
 	NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER,
@@ -75,6 +75,8 @@
 	NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER_EXCEPTION,
 	NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US,
 	NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS,
+	NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER,
+	NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER,
 	NSS_DYNAMIC_INTERFACE_TYPE_MAX
 };
 
diff --git a/exports/nss_gre.h b/exports/nss_gre.h
index 9ff8de8..1e49c48 100644
--- a/exports/nss_gre.h
+++ b/exports/nss_gre.h
@@ -71,8 +71,10 @@
  *	Message types for GRE requests and responses.
  */
 enum nss_gre_msg_types {
-	NSS_GRE_MSG_CONFIGURE = NSS_IF_MAX_MSG_TYPES + 1,
-	NSS_GRE_MSG_DECONFIGURE,
+	NSS_GRE_MSG_ENCAP_CONFIGURE = NSS_IF_MAX_MSG_TYPES + 1,
+	NSS_GRE_MSG_DECAP_CONFIGURE,
+	NSS_GRE_MSG_ENCAP_DECONFIGURE,
+	NSS_GRE_MSG_DECAP_DECONFIGURE,
 	NSS_GRE_MSG_SESSION_STATS,
 	NSS_GRE_MSG_BASE_STATS,
 	NSS_GRE_MSG_MAX
@@ -152,6 +154,7 @@
 	uint32_t mode;				/**< GRE TUN or TAP. */
 	uint32_t ip_type;			/**< IPv4 or IPv6 type. */
 	uint32_t next_node_if_num;		/**< To whom to forward packets. */
+	uint32_t sibling_if_num;        	/**< Sibling interface number. */
 	uint16_t src_mac[3];			/**< Source MAC address. */
 	uint16_t dest_mac[3];			/**< Destination MAC address. */
 	uint8_t ttl;				/**< TTL or HOPLIMIT. */
@@ -308,6 +311,7 @@
  * net_device
  *
  * @param[in] if_num         NSS interface number.
+ * @param[in] type           NSS interface type.
  * @param[in] gre_callback   Callback for the data.
  * @param[in] msg_callback   Callback for the message.
  * @param[in] netdev         Pointer to the associated network device.
@@ -316,7 +320,7 @@
  * @return
  * Pointer to the NSS core context.
  */
-extern struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, nss_gre_data_callback_t gre_callback,
+extern struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, uint32_t type, nss_gre_data_callback_t gre_callback,
 					nss_gre_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features);
 
 /**
diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h
index 449fe26..5ce8daa 100644
--- a/exports/nss_wifili_if.h
+++ b/exports/nss_wifili_if.h
@@ -745,6 +745,7 @@
 	uint32_t tx_success_bytes;	/**< Total number of bytes sent successfully. */
 	uint32_t tx_nawds_mcast_cnt;	/**< Total number of NAWDS multicast packets sent. */
 	uint32_t tx_nawds_mcast_bytes;	/**< Total number of NAWDS multicast bytes sent. */
+	uint32_t transmit_cnt;          /**< Total number of frames transmitted. */
 };
 
 /**
diff --git a/nss_core.c b/nss_core.c
index a83bc22..530703d 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -1462,7 +1462,7 @@
 	 */
 	nss_assert(if_map->magic == DEV_MAGIC);
 
-	nss_ctx->c2c_start = if_map->c2c_start;
+	nss_ctx->c2c_start = nss_ctx->meminfo_ctx.c2c_start_dma;
 
 	nss_top = nss_ctx->nss_top;
 	spin_lock_bh(&nss_top->lock);
diff --git a/nss_core.h b/nss_core.h
index 70471c7..1d3e170 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -623,8 +623,10 @@
 					/* map-t interface event callback function */
 	nss_gre_msg_callback_t gre_msg_callback;
 					/* gre interface event callback function */
-	nss_gre_data_callback_t gre_data_callback;
-					/* gre data callback function */
+	nss_gre_data_callback_t gre_inner_data_callback;
+					/* gre inner data callback function */
+	nss_gre_data_callback_t gre_outer_data_callback;
+					/* gre outer data callback function */
 	nss_tunipip6_msg_callback_t tunipip6_msg_callback;
 					/* ipip6 tunnel interface event callback function */
 	nss_pptp_msg_callback_t pptp_msg_callback;
diff --git a/nss_crypto_cmn.c b/nss_crypto_cmn.c
index cf5dfb4..a53afe0 100644
--- a/nss_crypto_cmn.c
+++ b/nss_crypto_cmn.c
@@ -21,6 +21,7 @@
 
 #include "nss_tx_rx_common.h"
 #include "nss_crypto_cmn.h"
+#include "nss_crypto_cmn_log.h"
 
 /*
  * Amount time the synchronous message should wait for response from
@@ -89,6 +90,11 @@
 	nss_core_log_msg_failures(nss_ctx, ncm);
 
 	/*
+	 * Trace messages.
+	 */
+	nss_crypto_cmn_log_rx_msg(nim);
+
+	/*
 	 * Load, Test & call
 	 */
 	cb = (nss_crypto_cmn_msg_callback_t)ncm->cb;
@@ -131,6 +137,11 @@
 			nss_ctx, ncm->version, ncm->interface, ncm->type,
 			(void *)ncm->cb, (void *)ncm->app_data, ncm->len);
 
+	/*
+	 * Trace messages.
+	 */
+	nss_crypto_cmn_log_tx_msg(msg);
+
 	return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
 }
 EXPORT_SYMBOL(nss_crypto_cmn_tx_msg);
diff --git a/nss_crypto_cmn_log.c b/nss_crypto_cmn_log.c
new file mode 100644
index 0000000..ed44f3c
--- /dev/null
+++ b/nss_crypto_cmn_log.c
@@ -0,0 +1,202 @@
+/*
+ **************************************************************************
+ * 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_crypto_cmn_log.c
+ *	NSS Crypto Common logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_crypto_cmn_log_message_types_str
+ *	Crypto Common message strings
+ */
+static int8_t *nss_crypto_cmn_log_message_types_str[NSS_CRYPTO_CMN_MSG_TYPE_MAX] __maybe_unused = {
+	"Crypto Common Invalid Message",
+	"Crypto Common CRYPTO CMN Initialize Node",
+	"Crypto Common Initialize Engine",
+	"Crypto Common Initialize DMA Pair",
+	"Crypto Common Update Context Information",
+	"Crypto Common Clear Context Information",
+	"Crypto Common Verify Context Active",
+	"Crypto Common Synchronous Node Statistics"
+	"Crypto Common Synchronouts Engine Statistics",
+	"Crypto Common Synchronous Context Statistics"
+};
+
+/*
+ * nss_crypto_cmn_log_error_response_types_str
+ *	Strings for error types for crypto common messages
+ */
+static int8_t *nss_crypto_cmn_log_error_response_types_str[NSS_CRYPTO_CMN_MSG_ERROR_MAX] __maybe_unused = {
+	"Crypto Common No Error",
+	"Crypto Common Header Version Not Supported",
+	"Crypto Common Context Index out-of-range for node",
+	"Crypto Common DMA mask out-of-range",
+	"Crypto Common DMA count exceeds Token",
+	"Crypto Common Token Allocation failed",
+	"Crypto Common Context Index out-of-range",
+	"Crypto Common Context has references",
+	"Crypto Common Bad Context Size",
+	"Crypto Common Bad Algorithm",
+	"Crypto Common Context Allocation failed",
+	"Crypto Common Context has no references",
+	"Crypto Common Invalid Context Flags"
+};
+
+/*
+ * nss_crypto_cmn_node_msg()
+ *	Log NSS crypto common node message.
+ */
+static void nss_crypto_cmn_node_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	struct nss_crypto_cmn_node *ncnm __maybe_unused = &ncm->msg.node;
+	nss_trace("%p: NSS crypto common node message:\n"
+		"Crypto Common Max DMA Rings: %d\n"
+		"Crypto Common Max Contex: %d\n"
+		"Crypto Common Max Context Size: %d\n",
+		ncnm, ncnm->max_dma_rings,
+		ncnm->max_ctx, ncnm->max_ctx_size);
+}
+
+/*
+ * nss_crypto_cmn_engine_msg()
+ *	Log NSS crypto cmn engine message.
+ */
+static void nss_crypto_cmn_engine_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	struct nss_crypto_cmn_engine *ncem __maybe_unused = &ncm->msg.eng;
+	nss_trace("%p: NSS crypto common engine message \n"
+		"Crypto Common Firmware Version: %p\n"
+		"Crypto Common DMA Mask: %x\n"
+		"Crypto Common Token Count: %d\n",
+		ncem, &ncem->fw_ver,
+		ncem->dma_mask, ncem->req_count);
+}
+
+/*
+ * nss_crypto_cmn_dma_msg()
+ *	Log NSS crypto cmn dma message.
+ */
+static void nss_crypto_cmn_dma_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	struct nss_crypto_cmn_dma *ncdm __maybe_unused = &ncm->msg.dma;
+	nss_trace("%p: NSS crypto common dma message \n"
+		"Crypto Common DMA Pair ID: %d\n",
+		ncdm, ncdm->pair_id);
+}
+
+/*
+ * nss_crypto_cmn_ctx_msg()
+ *	Log NSS crypto cmn context message.
+ */
+static void nss_crypto_cmn_ctx_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	struct nss_crypto_cmn_ctx *nccm __maybe_unused = &ncm->msg.ctx;
+	nss_trace("%p: NSS crypto common context message \n"
+		"Crypto Common Context Spare Words: %p\n"
+		"Crypto Common Index: %d\n"
+		"Crypto Common Secure Offset: %d\n"
+		"Crypto Common Cipher Key: %p\n"
+		"Crypto Common Authorization Key: %p\n"
+		"Crypto Common Nonce Value: %p\n"
+		"Crypto Common Algorithm: %x\n"
+		"Crypto Common Context Specific Flags: %x\n",
+		nccm, &nccm->spare,
+		nccm->index, nccm->sec_offset,
+		&nccm->cipher_key, &nccm->auth_key,
+		&nccm->nonce, nccm->algo, nccm->flags);
+}
+
+/*
+ * nss_crypto_cmn_log_verbose()
+ *	Log message contents.
+ */
+static void nss_crypto_cmn_log_verbose(struct nss_crypto_cmn_msg *ncm)
+{
+	switch (ncm->cm.type) {
+	case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_NODE:
+		nss_crypto_cmn_node_msg(ncm);
+		break;
+
+	case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_ENG:
+		nss_crypto_cmn_engine_msg(ncm);
+		break;
+
+	case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_DMA:
+		nss_crypto_cmn_dma_msg(ncm);
+		break;
+
+	case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_CTX:
+		nss_crypto_cmn_ctx_msg(ncm);
+		break;
+
+	default:
+		nss_warning("%p: Invalid message type\n", ncm);
+		break;
+	}
+}
+
+/*
+ * nss_crypto_cmn_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_crypto_cmn_log_tx_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	if (ncm->cm.type >= NSS_CRYPTO_CMN_MSG_TYPE_MAX) {
+		nss_warning("%p: Invalid message type\n", ncm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type]);
+	nss_crypto_cmn_log_verbose(ncm);
+}
+
+/*
+ * nss_crypto_cmn_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_crypto_cmn_log_rx_msg(struct nss_crypto_cmn_msg *ncm)
+{
+	if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", ncm);
+		return;
+	}
+
+	if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type,
+			nss_crypto_cmn_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response]);
+		goto verbose;
+	}
+
+	if (ncm->cm.error >= NSS_CRYPTO_CMN_MSG_ERROR_MAX) {
+		nss_warning("%p: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n",
+			ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+			ncm->cm.error);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n",
+		ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type],
+		ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+		ncm->cm.error, nss_crypto_cmn_log_error_response_types_str[ncm->cm.error]);
+
+verbose:
+	nss_crypto_cmn_log_verbose(ncm);
+}
diff --git a/nss_crypto_cmn_log.h b/nss_crypto_cmn_log.h
new file mode 100644
index 0000000..f78a8ec
--- /dev/null
+++ b/nss_crypto_cmn_log.h
@@ -0,0 +1,37 @@
+/*
+ ******************************************************************************
+ * 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_CRYPTO_CMN_LOG_H__
+#define __NSS_CRYPTO_CMN_LOG_H__
+
+/*
+ * nss_crypto_cmn_log.h
+ *	NSS Crypto Common Log header file.
+ */
+
+/*
+ * nss_crypto_cmn_log_tx_msg
+ *	Logs a crypto common message that is sent to the NSS firmware.
+ */
+void nss_crypto_cmn_log_tx_msg(struct nss_crypto_cmn_msg *ncm);
+
+/*
+ * nss_crypto_cmn_log_rx_msg
+ *	Logs a crypto common message that is received from the NSS firmware.
+ */
+void nss_crypto_cmn_log_rx_msg(struct nss_crypto_cmn_msg *ncm);
+
+#endif /* __NSS_CRYPTO_CMN_LOG_H__ */
diff --git a/nss_gre.c b/nss_gre.c
index e262154..fb510e0 100644
--- a/nss_gre.c
+++ b/nss_gre.c
@@ -33,10 +33,10 @@
 static atomic64_t pkt_cb_addr = ATOMIC64_INIT(0);
 
 /*
- * nss_gre_rx_handler()
- *	GRE rx handler.
+ * nss_gre_inner_rx_handler()
+ *	GRE inner rx handler.
  */
-static void nss_gre_rx_handler(struct net_device *dev, struct sk_buff *skb,
+static void nss_gre_inner_rx_handler(struct net_device *dev, struct sk_buff *skb,
 		    __attribute__((unused)) struct napi_struct *napi)
 {
 	nss_gre_data_callback_t cb;
@@ -49,7 +49,28 @@
 		}
 	}
 
-	cb = nss_top_main.gre_data_callback;
+	cb = nss_top_main.gre_inner_data_callback;
+	cb(dev, skb, 0);
+}
+
+/*
+ * nss_gre_outer_rx_handler()
+ *	GRE outer rx handler.
+ */
+static void nss_gre_outer_rx_handler(struct net_device *dev, struct sk_buff *skb,
+		    __attribute__((unused)) struct napi_struct *napi)
+{
+	nss_gre_data_callback_t cb;
+
+	nss_gre_pkt_callback_t scb = (nss_gre_pkt_callback_t)(unsigned long)atomic64_read(&pkt_cb_addr);
+	if (unlikely(scb)) {
+		struct nss_gre_info *info = (struct nss_gre_info *)netdev_priv(dev);
+		if (likely(info->next_dev)) {
+			scb(info->next_dev, skb);
+		}
+	}
+
+	cb = nss_top_main.gre_outer_data_callback;
 	cb(dev, skb, 0);
 }
 
@@ -255,7 +276,7 @@
  * nss_gre_register_if()
  *	Register data and message handlers for GRE.
  */
-struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, nss_gre_data_callback_t data_callback,
+struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, uint32_t type, nss_gre_data_callback_t data_callback,
 			nss_gre_msg_callback_t event_callback, struct net_device *netdev, uint32_t features)
 {
 	struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id];
@@ -263,10 +284,25 @@
 	nss_assert(nss_ctx);
 	nss_assert(nss_is_dynamic_interface(if_num));
 
-	nss_core_register_subsys_dp(nss_ctx, if_num, nss_gre_rx_handler, NULL, netdev, netdev, features);
+	switch (type) {
+	case NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER:
+		nss_core_register_subsys_dp(nss_ctx, if_num, nss_gre_inner_rx_handler, NULL, netdev, netdev, features);
+		nss_top_main.gre_inner_data_callback = data_callback;
+		break;
+
+	case NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER:
+		nss_core_register_subsys_dp(nss_ctx, if_num, nss_gre_outer_rx_handler, NULL, netdev, netdev, features);
+		nss_top_main.gre_outer_data_callback = data_callback;
+		break;
+
+	default:
+		nss_warning("%p: Unable to register. Wrong interface type %d\n", nss_ctx, type);
+		return NULL;
+	}
+
+	nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type);
 
 	nss_top_main.gre_msg_callback = event_callback;
-	nss_top_main.gre_data_callback = data_callback;
 
 	nss_core_register_handler(nss_ctx, if_num, nss_gre_msg_handler, NULL);
 
@@ -283,12 +319,19 @@
 void nss_gre_unregister_if(uint32_t if_num)
 {
 	struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id];
+	struct net_device *dev;
 
 	nss_assert(nss_ctx);
 	nss_assert(nss_is_dynamic_interface(if_num));
 
-	nss_core_unregister_subsys_dp(nss_ctx, if_num);
+	dev = nss_cmn_get_interface_dev(nss_ctx, if_num);
+	if (!dev) {
+		nss_warning("%p: Unable to find net device for the interface %d\n", nss_ctx, if_num);
+		return;
+	}
 
+	nss_core_unregister_subsys_dp(nss_ctx, if_num);
+	nss_core_set_subsys_dp_type(nss_ctx, dev, if_num, NSS_DYNAMIC_INTERFACE_TYPE_NONE);
 	nss_top_main.gre_msg_callback = NULL;
 
 	nss_core_unregister_handler(nss_ctx, if_num);
diff --git a/nss_gre_stats.c b/nss_gre_stats.c
index 7bead7b..e5226be 100644
--- a/nss_gre_stats.c
+++ b/nss_gre_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.
@@ -124,6 +124,7 @@
 void nss_gre_stats_session_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num)
 {
 	int i, j;
+	enum nss_dynamic_interface_type interface_type = nss_dynamic_interface_get_type(nss_ctx, if_num);
 
 	spin_lock_bh(&nss_gre_stats_lock);
 	for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
@@ -131,6 +132,12 @@
 			for (j = 0; j < NSS_GRE_STATS_SESSION_DEBUG_MAX; j++) {
 				session_debug_stats[i].stats[j] += sstats->stats[j];
 			}
+
+			if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER) {
+				session_debug_stats[i].stats[NSS_GRE_STATS_SESSION_ENCAP_RX_RECEIVED] += sstats->node_stats.rx_packets;
+			} else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER) {
+				session_debug_stats[i].stats[NSS_GRE_STATS_SESSION_DECAP_TX_FORWARDED] += sstats->node_stats.tx_packets;
+			}
 			break;
 		}
 	}
diff --git a/nss_hlos_if.h b/nss_hlos_if.h
index bcef4aa..6c64160 100644
--- a/nss_hlos_if.h
+++ b/nss_hlos_if.h
@@ -347,6 +347,6 @@
 			/* Index number for the next descriptor that will be written by the HLOS in the H2N0 descriptor ring (HLOS owned) */
 	volatile uint32_t n2h_hlos_index[15];
 			/* Index number for the next descriptor that will be read by the HLOS in the N2H0 descriptor ring (HLOS owned) */
-	uint32_t c2c_start;	/* Reserved for future use */
+	uint32_t reserved;	/* Reserved for future use */
 };
 #endif /* __NSS_HLOS_IF_H */
diff --git a/nss_meminfo.c b/nss_meminfo.c
index 719a4aa..1a0d36f 100644
--- a/nss_meminfo.c
+++ b/nss_meminfo.c
@@ -305,6 +305,11 @@
 			mem_ctx->logbuffer = (struct nss_log_descriptor *)kern_addr;
 		}
 
+		if (!strcmp(r->name, "c2c_descs_if_mem_map")) {
+			mem_ctx->c2c_start_memtype = mtype;
+			mem_ctx->c2c_start_dma = dma_addr;
+		}
+
 		/*
 		 * Flush the updated meminfo request.
 		 */
diff --git a/nss_meminfo.h b/nss_meminfo.h
index d2f5d1e..c9bb3b9 100644
--- a/nss_meminfo.h
+++ b/nss_meminfo.h
@@ -115,6 +115,8 @@
 	struct nss_log_descriptor *logbuffer;		/* nss_logbuffer virtual address */
 	uint32_t logbuffer_dma;				/* nss_logbuffer physical address */
 	enum nss_meminfo_memtype logbuffer_memtype;	/* Memory type for logbuffer */
+	uint32_t c2c_start_dma;				/* nss_c2c start physical address */
+	enum nss_meminfo_memtype c2c_start_memtype;	/* Memory type for c2c_start */
 	struct nss_meminfo_map meminfo_map;		/* Meminfo map */
 	struct nss_meminfo_block_list block_lists[NSS_MEMINFO_MEMTYPE_MAX];
 							/* Block lists for each memory type */