Merge "[qca-nss-drv] Added statistics for worker threads."
diff --git a/Makefile b/Makefile
index 0475975..4cab556 100644
--- a/Makefile
+++ b/Makefile
@@ -54,6 +54,7 @@
 			nss_tunipip6.o \
 			nss_virt_if.o \
 			nss_vlan.o \
+			nss_tstamp.o \
 			nss_wifi.o \
 			nss_wifi_vdev.o \
 			nss_wifi_if.o \
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 10260ac..d23e18c 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -206,6 +206,24 @@
 		/**< Special interface number for project node. */
 
 /**
+ * Wireless Multimedia Extention Access Category to TID.
+ */
+#define NSS_WIFILI_WME_AC_TO_TID(_ac) (	\
+		((_ac) == NSS_WIFILI_WME_AC_VO) ? 6 : \
+		(((_ac) == NSS_WIFILI_WME_AC_VI) ? 5 : \
+		(((_ac) == NSS_WIFILI_WME_AC_BK) ? 1 : \
+		0)))
+
+/**
+ * Wireless TID to Wireless Extension Multimedia Access Category.
+ */
+#define NSS_WIFILI_TID_TO_WME_AC(_tid) (	\
+		(((_tid) == 0) || ((_tid) == 3)) ? NSS_WIFILI_WME_AC_BE : \
+		((((_tid) == 1) || ((_tid) == 2)) ? NSS_WIFILI_WME_AC_BK : \
+		((((_tid) == 4) || ((_tid) == 5)) ? NSS_WIFILI_WME_AC_VI : \
+		NSS_WIFILI_WME_AC_VO)))
+
+/**
  * Converts the format of an IPv6 address from Linux to NSS. @hideinitializer
  */
 #define IN6_ADDR_TO_IPV6_ADDR(ipv6, in6) \
diff --git a/exports/nss_cmn.h b/exports/nss_cmn.h
index ed464b5..cb078a0 100644
--- a/exports/nss_cmn.h
+++ b/exports/nss_cmn.h
@@ -252,7 +252,7 @@
  * @return
  * TRUE if the number is a virtual interface. Otherwise FALSE.
  */
-extern bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num);
+extern bool nss_cmn_interface_is_virtual(struct nss_ctx_instance *nss_ctx, int32_t interface_num);
 
 /**
  * nss_cmn_get_interface_dev
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index 7441a06..fc1e940 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -111,20 +111,6 @@
 };
 
 /**
- * nss_dynamic_interface_pvt
- *	Private data information for the dynamic interface.
- */
-struct nss_dynamic_interface_pvt {
-	struct semaphore sem;		/**< Semaphore for sending one message at a time. */
-	struct completion complete;	/**< Blocks the thread until an acknowledgment is received. */
-	int current_if_num;		/**< Current interface number. */
-	enum nss_cmn_response response;
-		/**< Holds the return message from NSS firmware. */
-	nss_dynamic_interface_assigned type[NSS_MAX_DYNAMIC_INTERFACES];
-					/**< Array of assigned interface types. */
-};
-
-/**
  * nss_dynamic_interface_alloc_node
  *	Allocates a node for a dynamic interface.
  *
@@ -170,12 +156,13 @@
  * nss_dynamic_interface_get_type
  *	Returns the type of dynamic interface.
  *
- * @param[in] if_num  Dynamic interface number.
+ * @param[in] nss_ctx  Pointer to the NSS context.
+ * @param[in] if_num   Interface number of dynamic interface.
  *
  * @return
  * Type of dynamic interface per the dynamic interface number.
  */
-extern enum nss_dynamic_interface_type nss_dynamic_interface_get_type(int if_num);
+extern enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num);
 
 /**
  * nss_dynamic_interface_tx
diff --git a/exports/nss_edma.h b/exports/nss_edma.h
index b1129d2..d21b3e6 100644
--- a/exports/nss_edma.h
+++ b/exports/nss_edma.h
@@ -144,13 +144,14 @@
 struct nss_edma_misc_err_stats {
 	uint32_t axi_rd_err;            /**< EDMA AXI read error. */
 	uint32_t axi_wr_err;            /**< EDMA AXI write error. */
-	uint32_t rx_desc_fifo_full_err;	/**< EDMA Receive descriptor FIFO full error. */
-	uint32_t rx_buf_size_err;       /**< EDMA Receive buffer size error. */
-	uint32_t tx_sram_full_err;      /**< EDMA Transmit SRAM full error. */
-	uint32_t tx_cmpl_buf_full_err;  /**< EDMA Transmit completion buffer full error. */
+	uint32_t rx_desc_fifo_full_err;	/**< EDMA receive descriptor FIFO full error. */
+	uint32_t rx_buf_size_err;       /**< EDMA receive buffer size error. */
+	uint32_t tx_sram_full_err;      /**< EDMA transmit SRAM full error. */
+	uint32_t tx_cmpl_buf_full_err;  /**< EDMA transmit completion buffer full error. */
 	uint32_t pkt_len_la64k_err;     /**< EDMA packet length greater than 64k error. */
 	uint32_t pkt_len_le33_err;      /**< EDMA packet length smaller than 33b error. */
 	uint32_t data_len_err;          /**< EDMA data length error. */
+	uint32_t alloc_fail_cnt;	/**< EDMA number of times the allocation of pbuf for statistics failed. */
 };
 
 /**
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index d135bbd..c05db64 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -43,6 +43,7 @@
 	NSS_IPV4_TX_CREATE_MC_RULE_MSG,
 	NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG,
 	NSS_IPV4_TX_ACCEL_MODE_CFG_MSG,
+	NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
 	NSS_IPV4_MAX_MSG_TYPES,
 };
 
@@ -335,6 +336,17 @@
 };
 
 /**
+ * nss_ipv4__inquiry_msg
+ *	IPv4 connection inquiry naming structure.
+ */
+struct nss_ipv4_inquiry_msg {
+	/*
+	 * Request by its 5 tuple and get Response for other items.
+	 */
+	struct nss_ipv4_rule_create_msg rr;
+};
+
+/**
  * nss_ipv4_mc_if_rule
  *	IPv4 multicast rule for creating per-interface information.
  */
@@ -677,6 +689,8 @@
 				/**< Synchronize multiple connection statistics. */
 		struct nss_ipv4_accel_mode_cfg_msg accel_mode_cfg;
 				/**< Acceleration mode. */
+		struct nss_ipv4_inquiry_msg inquiry;
+				/**< Inquiry if a connection has created. */
 	} msg;			/**< Message payload. */
 };
 
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 49aaf4f..2d2566f 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -43,6 +43,7 @@
 	NSS_IPV6_TX_CREATE_MC_RULE_MSG,
 	NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG,
 	NSS_IPV6_TX_ACCEL_MODE_CFG_MSG,
+	NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
 	NSS_IPV6_MAX_MSG_TYPES,
 };
 
@@ -398,6 +399,17 @@
 };
 
 /**
+ * nss_ipv6_inquiry_msg
+ *	IPv6 connection inquiry sub-messages.
+ */
+struct nss_ipv6_inquiry_msg {
+	/*
+	 * Request by 5 tuple, and Response in other items.
+	 */
+	struct nss_ipv6_rule_create_msg rr;
+};
+
+/**
  * nss_ipv6_mc_if_rule
  *	IPv6 multicast rule for creating a per-interface payload.
  */
@@ -642,6 +654,8 @@
 				/**< Synchronize multiple connection statistics. */
 		struct nss_ipv6_accel_mode_cfg_msg accel_mode_cfg;
 				/**< Configure acceleration mode. */
+		struct nss_ipv6_inquiry_msg inquiry;
+				/**< Inquiry if a connection has been created. */
 	} msg;			/**< Message payload. */
 };
 
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 8ebcd07..4ea418b 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -29,6 +29,10 @@
 
 #define MAX_PAGES_PER_MSG 32	/**< Maximum number of pages per message. */
 
+#define NSS_MAX_NUM_PRI 4		/**< Maximum number of pnode ingress priorities. */
+#define NSS_DEFAULT_NUM_PRI 1		/**< Default priority. */
+#define NSS_DEFAULT_QUEUE_LIMIT 256	/**< Default pnode queue limit. */
+
 /**
  * nss_n2h_cfg_pvt
  *	N2H private data configuration.
@@ -60,6 +64,7 @@
 	NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
 	NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
 	NSS_TX_DDR_INFO_VIA_N2H_CFG,
+	NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
 	NSS_METADATA_TYPE_N2H_MAX,
 };
 
@@ -110,6 +115,21 @@
 };
 
 /**
+ * nss_n2h_pnode_queue_config
+ *	N2H pnode queue configuration.
+ */
+struct nss_n2h_pnode_queue_config {
+	uint8_t num_pri;	/**< Maximum number of priorities. */
+	uint8_t mq_en;		/**< Enable multiple queues. */
+	uint16_t reserved1;	/**< Reserved for alignment. */
+	uint16_t qlimits[NSS_MAX_NUM_PRI];
+				/**< Limits of each queue. */
+#if (NSS_MAX_NUM_PRI & 1)
+	uint16_t reserved2;
+#endif
+};
+
+/**
  * nss_n2h_empty_pool_buf
  *	Old way of setting the number of empty pool buffers (payloads).
  *
@@ -265,6 +285,8 @@
 				/**< Sets the number of Wi-Fi payloads. */
 		struct nss_mmu_ddr_info mmu;
 				/**< Gets the DDR size and start address to configure the MMU. */
+		struct nss_n2h_pnode_queue_config pn_q_cfg;
+				/**< Pnode queueing configuration. */
 	} msg;			/**< Message payload. */
 };
 
@@ -352,9 +374,21 @@
 			nss_n2h_msg_callback_t cb, void *app_data);
 
 /**
+ * nss_n2h_update_queue_config
+ *	Update pnode queue configuration to NSS.
+ *
+ * @param[in] max_pri  Maximum number of ingress priorities.
+ * @param[in] mq_en    Enable multiple pnode queues.
+ * @param[in] pri_num  Number of ingress priorities.
+ * @param[in] qlimits  Maximum number of packets in each queues.
+ *
+ * @return
+ * Status of the configuration update operation.
+ */
+extern nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int pri_num, int *qlimits);
+
+/**
  * @}
  */
 
 #endif /* __NSS_N2H_H */
-
-
diff --git a/exports/nss_ppe.h b/exports/nss_ppe.h
index 1d1258b..d9f534b 100644
--- a/exports/nss_ppe.h
+++ b/exports/nss_ppe.h
@@ -39,6 +39,7 @@
  */
 enum nss_ppe_metadata_types {
 	NSS_PPE_MSG_SYNC_STATS,
+	NSS_PPE_MSG_L2_EXCEPTION,
 	NSS_PPE_MSG_MAX,
 };
 
@@ -108,6 +109,14 @@
 			/**< Request failed because the flow QoS group is full. */
 };
 
+/*
+ * nss_ppe_l2_exception_msg
+ *	Message structure for L2 exception.
+ */
+struct nss_ppe_l2_exception_msg {
+	uint32_t l2_exception_enable;   /**< Enable/Disable L2 exception */
+};
+
 /**
  * nss_ppe_msg
  *	Data for sending and receiving PPE host-to-NSS messages.
@@ -121,10 +130,23 @@
 	union {
 		struct nss_ppe_sync_stats_msg stats;
 				/**< Synchronization statistics. */
+		struct nss_ppe_l2_exception_msg l2_exception;
+				/**< L2 exception message. */
 	} msg;			/**< Message payload. */
 };
 
 /**
+ * Callback function for receiving PPE messages.
+ *
+ * @datatypes
+ * nss_ppe_msg
+ *
+ * @param[in] app_data  Pointer to the application context of the message.
+ * @param[in] msg       Pointer to the message data.
+ */
+typedef void (*nss_ppe_msg_callback_t)(void *app_data, struct nss_ppe_msg *msg);
+
+/**
  * nss_ppe_register_handler
  *	Registers the PPE interface with NSS.
  *
@@ -134,6 +156,78 @@
 extern void nss_ppe_register_handler(void);
 
 /**
+ * nss_ppe_tx_msg
+ *	Sends PPE messages to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ppe_msg
+ *
+ * @param[in] nss_ctx  Pointer to the NSS context.
+ * @param[in] msg      Pointer to the message data.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
+
+/**
+ * nss_ppe_tx_msg_sync
+ *	Sends PPE messages synchronously to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ppe_msg
+ *
+ * @param[in]     nss_ctx  Pointer to the NSS context.
+ * @param[in,out] msg      Pointer to the message data.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
+
+/**
+ * nss_ppe_msg_init
+ *	Initializes a PPE message.
+ *
+ * @datatypes
+ * nss_ppe_msg
+ *
+ * @param[in,out] ncm       Pointer to the message.
+ * @param[in]     if_num    Interface number
+ * @param[in]     type      Type of message.
+ * @param[in]     len       Size of the payload.
+ * @param[in]     cb        Callback function for the message.
+ * @param[in]     app_data  Pointer to the application context of the message.
+ *
+ * @return
+ * None.
+ */
+void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type,  uint32_t len, void *cb, void *app_data);
+
+/**
+ * nss_ppe_get_context
+ *	Gets the PPE context used in nss_ppe_tx.
+ *
+ * @return
+ * Pointer to the NSS core context.
+ */
+struct nss_ctx_instance *nss_ppe_get_context(void);
+
+/**
+ * nss_ppe_tx_l2_exception_msg
+ *      Sends the PPE a message to enable/disable L2 exceptions.
+ *
+ * @param[in] if_num  Interface number of the PPE.
+ * @param[in] exception_enable  Enable/disable flag.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+nss_tx_status_t nss_ppe_tx_l2_exception_msg(uint32_t if_num, bool exception_enable);
+
+/**
  * nss_ppe_stats_conn_get
  *	Gets PPE connection statistics.
  *
diff --git a/exports/nss_tstamp.h b/exports/nss_tstamp.h
new file mode 100644
index 0000000..001a1b7
--- /dev/null
+++ b/exports/nss_tstamp.h
@@ -0,0 +1,55 @@
+
+/*
+ **************************************************************************
+ * Copyright (c) 2017, 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_tstamp.h
+ *	NSS to HLOS Tstamp interface definitions.
+ */
+
+#ifndef __NSS_TSTAMP_H
+#define __NSS_TSTAMP_H
+
+/**
+ * @brief Metadata added by the tstamp HLOS driver
+ * while sending the packet to NSS tstamp module.
+ */
+struct nss_tstamp_h2n_pre_hdr {
+	uint32_t ts_ifnum;	/**< Time stamp interface number. */
+	uint32_t ts_tx_hdr_sz;	/**< Total header size. */
+};
+
+/**
+ * @brief Metadata added by the NSS tstamp module before sending
+ * the packet to host.
+ */
+struct nss_tstamp_n2h_pre_hdr {
+	uint32_t ts_ifnum;	/**< Time stamp interface number. */
+	uint32_t ts_data_lo;	/**< Time stamp lower order bits. */
+	uint32_t ts_data_hi;	/**< Time stamp higher order bits. */
+
+	uint32_t ts_tx;		/**< Time stamp direction. */
+	uint32_t ts_hdr_sz;	/**< Size of the header including the skb data alignment padding. */
+};
+
+/**
+ * @brief transfer the packet to Tstamp NSS module
+ *
+ * @return nss_tx_status
+ */
+nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num);
+
+#endif /* __NSS_TSTAMP_H */
diff --git a/exports/nss_wifi_vdev.h b/exports/nss_wifi_vdev.h
index 035afb8..b62d850 100644
--- a/exports/nss_wifi_vdev.h
+++ b/exports/nss_wifi_vdev.h
@@ -398,6 +398,8 @@
 struct nss_wifi_vdev_mesh_per_packet_metadata {
 	uint32_t status;	/**< Meshmode Status. */
 	uint32_t rssi;		/**< RSSI. */
+	uint32_t tsf;		/**< Tx expiry time. */
+	uint16_t tx_retries;	/**< Retry count. */
 };
 
 /**
@@ -549,8 +551,14 @@
  *	Metadata payload for Mesh mode receive.
  */
 struct nss_wifi_vdev_meshmode_rx_metadata {
+	uint16_t rs_ratephy;	/**< PHY rate. */
 	uint16_t vdev_id;	/**< Virtual device ID. */
 	uint16_t peer_id;	/**< Peer ID. */
+	uint16_t rs_rssi;	/**< RSSI (noise floor adjusted). */
+	uint8_t rs_flags;	/**< First/last MSDU flags. */
+	uint8_t rs_channel;	/**< Operational channel. */
+	uint8_t rs_keyix;	/**< Key index. */
+	uint8_t padd;		/**< Padding to ensure alignment. */
 };
 
 /**
diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h
index 0bba091..331f84e 100644
--- a/exports/nss_wifili_if.h
+++ b/exports/nss_wifili_if.h
@@ -17,33 +17,80 @@
  /**
   * @file nss_wifili.h
   *	NSS TO HLOS interface definitions.
+  *	NOTE: Here we will use wifili as a reference to
+  *	the IPQ807x Wi-Fi object.
   */
 #ifndef __NSS_WIFILI_H
 #define __NSS_WIFILI_H
 
 #define NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG 2
-				/**< Max srng register groups. */
+				/**< Maximum srng (ring) register groups. */
 #define NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG 32
-				/**< Max number of pages allocated from host. */
+				/**< Maximum number of pages allocated from host. */
 #define NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG 4
-				/**< Max number of tcl data ring for NSS. */
+				/**< Maximum number of Transmit Classifier data ring for NSS. */
 #define NSS_WIFILI_MAX_REO_DATA_RINGS_MSG 4
-				/**< Max number of reo data ring for NSS. */
+				/**< Maximum number of Reorder (reo) data ring for NSS. */
 #define NSS_WIFILI_SOC_PER_PACKET_METADATA_OFFSET 4
-				/**< Metadata area for storing rx stats. */
+				/**< Metadata area for storing Rx statistics. */
 #define NSS_WIFILI_MAX_TXDESC_POOLS_MSG 4
-				/**< Max number of txdesc sw pools */
+				/**< Maximum number of Tx Descriptor software pools. */
 #define NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG 4
-				/**< Max number of txdesc ext sw pools */
+				/**< Maximum number of Tx Descriptor Extended software pools. */
 #define NSS_WIFILI_MAX_PDEV_NUM_MSG 3
-				/**< Max number of pdev devices*/
+				/**< Maximum number of pdev devices. */
+#define NSS_WIFILI_MAX_MCS 12
+				/**< Maximum Modulaton And Coding Scheme (MCS) count. */
+#define NSS_WIFILI_MAX_MCS_11A 8
+				/**< Maximum MCS for 11a mode. */
+#define NSS_WIFILI_MAX_MCS_11B 7
+				/**< Maximum MCS for 11b mode. */
+#define NSS_WIFILI_MAX_MCS_11AC 10
+				/**< Maximum MCS for 11ac mode. */
+#define NSS_WIFILI_MAX_MCS_11AX 10
+				/**< Maximum MCS for 11ax mode. */
+#define NSS_WIFILI_SS_COUNT 8
+				/**< Maximum spatial streams count. */
+#define NSS_WIFILI_SUPPORTED_BW 4
+				/**< Maximum number of bandwidth supported. */
+#define NSS_WIFILI_REPT_MU_MIMO 1
+#define NSS_WIFILI_REPT_MU_OFDMA_MIMO 3
+#define NSS_WIFILI_SUPPORTED_RECEPTION_TYPES 4
+				/**< Maximum supported reception types. */
+#define NSS_WIFILI_SOC_PER_PACKET_METADATA_SIZE 60
+				/**< Metadata area total size. */
+
+/**
+ * nss_wifili_wme_stream_classes
+ *	WME stream classes.
+ */
+enum nss_wifili_wme_stream_classes {
+	NSS_WIFILI_WME_AC_BE,	/**< Best effort. */
+	NSS_WIFILI_WME_AC_BK,	/**< Background. */
+	NSS_WIFILI_WME_AC_VI,	/**< Video. */
+	NSS_WIFILI_WME_AC_VO,	/**< Voice. */
+	NSS_WIFILI_WME_AC_MAX	/**< Maximum AC Value. */
+};
+
+/**
+ * nss_wifili_packet_type
+ *	Different Packet Types.
+ */
+enum nss_wifili_packet_type {
+	NSS_WIFILI_DOT11_A,		/**< 802.11a packet type. */
+	NSS_WIFILI_DOT11_B,		/**< 802.11b packet type. */
+	NSS_WIFILI_DOT11_N,		/**< 802.11n packet type. */
+	NSS_WIFILI_DOT11_AC,		/**< 802.11ac packet type. */
+	NSS_WIFILI_DOT11_AX ,		/**< 802.11ax packet type. */
+	NSS_WIFILI_DOT11_MAX		/**< Maximum 802.11 packet types. */
+};
 
 /**
  * nss_wifili_msg_types
- *	nss_wifili messages
+ *	NSS wifili messages.
  */
 enum nss_wifili_msg_types {
-	NSS_WIFILI_INIT_MSG = 0,
+	NSS_WIFILI_INIT_MSG,
 	NSS_WIFILI_SOC_RESET_MSG,
 	NSS_WIFILI_PDEV_INIT_MSG,
 	NSS_WIFILI_PDEV_DEINIT_MSG,
@@ -55,454 +102,569 @@
 	NSS_WIFILI_PEER_FREELIST_APPEND_MSG,
 	NSS_WIFILI_STATS_MSG,
 	NSS_WIFILI_WDS_VENDOR_MSG,
+	NSS_WIFILI_PEER_STATS_MSG,
 	NSS_WIFILI_MAX_MSG
 };
 
 /**
- * wifili_error_types
- *	wifili msg error types
+ * nss_wifili_error_types
+ *	Wifili error message types for functions.
  */
-enum wifili_error_types {
-	NSS_WIFILI_EMSG_NONE = 0,
-			/**< no error */
+enum nss_wifili_error_types {
+	NSS_WIFILI_EMSG_NONE,
+			/**< No error. */
 	NSS_WIFILI_EMSG_RINGS_INIT_FAIL,
-			/**< device ring initialization fail */
+			/**< Device ring initialization failure. */
 	NSS_WIFILI_EMSG_PDEV_INIT_IMPROPER_STATE_FAIL,
-			/**< radio init fail due to improper state of device */
+			/**< Radio initialization failure due to improper state of device. */
 	NSS_WIFILI_EMSG_PDEV_INIT_INVALID_RADIOID_FAIL,
-			/**< radio init failed due to invalid radio id */
+			/**< Radio initialization failed due to invalid radio ID. */
 	NSS_WIFILI_EMSG_PDEV_RESET_INVALID_RADIOID_FAIL,
-			/**< radio reset failed due to invalid radio id */
+			/**< Radio reset failed due to invalid radio ID. */
 	NSS_WIFILI_EMSG_START_IMPROPER_STATE_FAIL,
-			/**< device start fail due to improper state */
+			/**< Device start failure due to improper state. */
 	NSS_WIFILI_EMSG_PEER_CREATE_FAIL,
-			/**< peed creat fail */
+			/**< Peer creation failure. */
 	NSS_WIFILI_EMSG_PEER_DELETE_FAIL,
-			/**< peer delete fail */
+			/**< Peer delete failure. */
 	NSS_WIFILI_EMSG_HASHMEM_INIT_FAIL,
-			/**< peer hash mem init fail */
+			/**< Peer hash memory initialization failure. */
 	NSS_WIFILI_EMSG_PEER_FREELIST_APPEND_FAIL,
-			/**< peer freelist append fail*/
+			/**< Peer freelist append failure. */
 	NSS_WIFILI_EMSG_PEER_CREATE_INVALID_VDEVID_FAIL,
-			/**< peer create fail due to invalide vdev_id */
+			/**< Peer creation failure due to invalid vdev ID. */
 	NSS_WIFILI_EMSG_PEER_CREATE_INVALID_PEER_ID_FAIL,
-			/**< peer create fail due to invalide peer_id */
+			/**< Peer creation failure due to invalid peer ID. */
 	NSS_WIFILI_EMSG_PEER_CREATE_VDEV_NULL_FAIL,
-			/**< peer create fail due to vdev null */
+			/**< Peer creation failure due to null vdev. */
 	NSS_WIFILI_EMSG_PEER_CREATE_PDEV_NULL_FAIL,
-			/**< peer create fail due to peer null */
+			/**< Peer creation failure due to null peer. */
 	NSS_WIFILI_EMSG_PEER_CREATE_ALLOC_FAIL,
-			/**< peer create fail due to mem alloc fail */
+			/**< Peer creation failure due to memory allocation failure. */
 	NSS_WIFILI_EMSG_PEER_DELETE_VAPID_INVALID_FAIL,
-			/**< peer delete fail due to invalide vdev_id */
+			/**< Peer delete failure due to invalid vdev_ID. */
 	NSS_WIFILI_EMSG_PEER_DELETE_INVALID_PEERID_FAIL,
-			/**< peer delete fail due to invalide peer_id */
+			/**< Peer delete failure due to invalid peer ID. */
 	NSS_WIFILI_EMSG_PEER_DELETE_VDEV_NULL_FAIL,
-			/**< peer delete fail due to vdev null */
+			/**< Peer delete failure due to null vdev. */
 	NSS_WIFILI_EMSG_PEER_DELETE_PDEV_NULL_FAIL,
-			/**< peer create fail due to pdev null */
+			/**< Peer creation failure due to null vdev. */
 	NSS_WIFILI_EMSG_PEER_DELETE_PEER_NULL_FAIL,
-			/**< peer create fail due to peer null */
+			/**< Peer creation failure due to null peer. */
 	NSS_WIFILI_EMSG_PEER_DELETE_PEER_CORRUPTED_FAIL,
-			/**< peer create fail due to corrupted peer  */
+			/**< Peer creation failure due to corrupted peer. */
 	NSS_WIFILI_EMSG_GROUP0_TIMER_ALLOC_FAIL,
-			/**< timer alloc fail */
+			/**< Timer allocation failure. */
 	NSS_WIFILI_EMSG_INSUFFICIENT_WT_FAIL,
-			/**< insufficient worker thread error */
+			/**< Insufficient worker thread error. */
 	NSS_WIFILI_EMSG_INVALID_NUM_TCL_RING_FAIL,
-			/**< invlalid number of tcl ring provided in init msg */
+			/**< Invlalid number of Transmit Classifier ring provided in initialization message. */
 	NSS_WIFILI_EMSG_INVALID_NUM_REO_DST_RING_FAIL,
-			/**< invalid number of reo dst ring in init msg */
+			/**< Invalid number of reorder destination ring in initialization message. */
 	NSS_WIFILI_EMSG_HAL_SRNG_SOC_ALLOC_FAIL,
-			/**< srng soc memory allocation failure */
+			/**< Srng SoC memory allocation failure. */
 	NSS_WIFILI_EMSG_HAL_TCL_SRNG_ALLOC_FAIL,
-			/**< tcl srng ring alloc fail */
+			/**< Transmit Classifier srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_TXCOMP_SRNG_ALLOC_FAIL,
-			/**< txcomp srng ring alloc fail */
+			/**< Txcomp srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_REODST_SRNG_ALLOC_FAIL,
-			/**< reo dst srng ring alloc fail */
+			/**< Reorder destination srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_REOREINJECT_SRNG_ALLOC_FAIL,
-			/**< reo reinject srng ring alloc fail */
+			/**< Reorder reinject srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_RXRELEASE_SRNG_ALLOC_FAIL,
-			/**< rx release srng ring alloc fail */
+			/**< Rx release srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_RXEXCP_SRNG_ALLOC_FAIL,
-			/**< rx exception srng ring alloc fail */
+			/**< Rx exception srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_TX_MEMALLOC_FAIL,
-			/**< tx hal srng ring alloc fail */
+			/**< Tx hal (hardware Abstraction Layer) srng ring allocation failure. */
 	NSS_WIFILI_EMSG_HAL_TX_INVLID_POOL_NUM_FAIL,
-			/**< invalid pool num in init msg  */
+			/**< Invalid pool number in initialization message. */
 	NSS_WIFILI_EMSG_HAL_TX_INVALID_PAGE_NUM_FAIL,
-			/**< invalid page num in init msg  */
+			/**< Invalid page numner in initialization message. */
 	NSS_WIFILI_EMSG_HAL_TX_DESC_MEM_ALLOC_FAIL,
-			/**< tx desc mem allocation fail  */
+			/**< Tx descriptor memory allocation failure. */
 	NSS_WIFILI_EMSG_HAL_RX_MEMALLOC_FAIL,
-			/**< rx memalloc fail */
+			/**< Rx memory allocation failure. */
 	NSS_WIFILI_EMSG_UNKNOWN
-			/**< unknown error message */
+			/**< Unknown error message. */
 };
 
 /**
- * wifili_soc_extended_data_types
- *	enumeration of extended data type to host
+ * nss_wifili_soc_extended_data_types
+ *	Enumeration of extended data type to host.
  */
-enum wifili_soc_extended_data_types {
-	WIFILI_SOC_EXT_DATA_PKT_TYPE_NONE,
-	WIFILI_SOC_EXT_DATA_PKT_MSDU_LINK_DESC,
-	WIFILI_SOC_EXT_DATA_PKT_TYPE_MAX
+enum nss_wifili_soc_extended_data_types {
+	WIFILI_SOC_EXT_DATA_PKT_TYPE_NONE,		/**< Packet type is none. */
+	WIFILI_SOC_EXT_DATA_PKT_MSDU_LINK_DESC,		/**< Packet type is MSDU link desctriptor. */
+	WIFILI_SOC_EXT_DATA_PKT_INVALID_PEER,		/**< Packet type is Invalid peer. */
+	WIFILI_SOC_EXT_DATA_PKT_TYPE_MAX		/**< Maximum extended data types. */
 };
 
 /**
  * nss_wifili_hal_srng_info
- *	wifili hal srng info
+ *	Wifili hal srng information.
  */
 struct nss_wifili_hal_srng_info{
 	uint8_t ring_id;
-			/**< ring id */
+			/**< Ring ID. */
 	uint8_t mac_id;
-			/**< pdev id */
+			/**< Pdev ID. */
 	uint8_t resv[2];
 	uint32_t ring_base_paddr;
-			/**< physical base address of the ring */
+			/**< Physical base address of the ring. */
 	uint32_t num_entries;
-			/**< number of entries in ring */
-	uint32_t flags;	/**< misc flags */
+			/**< Number of entries in ring. */
+	uint32_t flags;	/**< Miscellaneous flags. */
 	uint32_t ring_dir;
-			/**< ring direction: source or dest */
+			/**< Ring direction: source or destination. */
 	uint32_t entry_size;
-			/**< ring entry size */
+			/**< Ring entry size. */
 	uint32_t low_threshold;
-			/**< Low threshold – in number of ring entries (valid for src rings only) */
+			/**< Low threshold – in number of ring entries (valid for source rings only). */
 	uint32_t hwreg_base[NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG];
-			/**< hw ring base address */
+			/**< Hardware ring base address. */
 };
 
 /**
  * nss_wifili_hal_srng_soc_msg
- *	wifi li hal srng message
+ *	Wifili hal srng message.
  */
 struct nss_wifili_hal_srng_soc_msg {
 	uint32_t dev_base_addr;
-			/**< base address of wlan dev */
+			/**< Base address of wlan dev. */
 	uint32_t shadow_rdptr_mem_addr;
-			/**< shadow rdptr address */
+			/**< Shadow read pointer address. */
 	uint32_t shadow_wrptr_mem_addr;
-			/**< shadow wrptr address */
+			/**< Shadow write pointer address. */
 };
 
 /**
  * nss_wifili_tx_desc_init_msg
- *	wifi li software desc pool init msg
+ *	Wifili software descriptor pool initialization message.
  */
 struct nss_wifili_tx_desc_init_msg {
 	uint32_t num_tx_desc;
-			/**< count of the sw descriptors */
+			/**< Count of the software descriptors. */
 	uint32_t num_tx_desc_ext;
-			/**< count of sw extention descriptors */
+			/**< Count of software extented descriptors. */
 	uint32_t num_pool;
-			/**< number of descriptor pools */
+			/**< Number of descriptor pools. */
 	uint32_t memory_addr[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG];
-			/**< memory start address of each page */
+			/**< Memory start address of each page. */
 	uint32_t memory_size[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG];
-			/**< memory size */
+			/**< Memory size. */
 	uint32_t num_memaddr;
-			/**< number of mem address */
+			/**< Number of memory address. */
 	uint32_t ext_desc_page_num;
-			/**< ext_desc_page number */
+			/**< Extended descriptor page number. */
 };
 
 /**
  * nss_wifili_init_msg
- *	Lithium soc init msg
+ *	Wifili SoC initialization message.
  */
 struct nss_wifili_init_msg {
 	struct nss_wifili_hal_srng_soc_msg hssm;
 	uint8_t num_tcl_data_rings;
-			/**< number of tcl data rings */
+			/**< Number of Transmit Classifier data rings. */
 	uint8_t num_reo_dest_rings;
-			/**< number of reo rings */
+			/**< Number of reorder rings. */
 	uint8_t resv[2];
-			/**< reserve for alignment */
+			/**< Reserve for alignment. */
 	struct nss_wifili_hal_srng_info tcl_ring_info[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
-			/**< tcl data ring config info */
+			/**< Transmit Classifier data ring configuration information. */
 	struct nss_wifili_hal_srng_info tx_comp_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
-			/**< tx completion ring config info */
+			/**< Tx completion ring configuration information. */
 	struct nss_wifili_hal_srng_info reo_dest_ring[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG];
-			/**< reo destination ring config info */
+			/**< Reorder destination ring configuration information. */
 	struct nss_wifili_hal_srng_info reo_exception_ring;
-			/**< reo exception ring config info */
+			/**< Reorder exception ring configuration information. */
 	struct nss_wifili_hal_srng_info rx_rel_ring;
-			/**< wbm release ring config info */
+			/**< WBM (Wireless Buffer manager) release ring configuration information. */
 	struct nss_wifili_hal_srng_info reo_reinject_ring;
-			/**< reinject ring config info */
+			/**< Reinject ring configuration information. */
 	struct nss_wifili_tx_desc_init_msg wtdim;
-			/**< tx descriptor init message */
+			/**< Tx descriptor initialization message. */
 };
 
 /**
  * nss_wifili_pdev_deinit_msg
- *	li pdev deinit msg
+ *	Wifili pdev deinit message.
  */
 struct nss_wifili_pdev_deinit_msg {
-	uint32_t ifnum;	/**< nss ifnum of pdev */
+	uint32_t ifnum;	/**< NSS interface number of pdev. */
 };
 
 /**
  * nss_wifili_pdev_init_msg
- *	li pdev init msg
+ *	Wifili pdev initialization message.
  */
 struct nss_wifili_pdev_init_msg {
 	struct nss_wifili_hal_srng_info rxdma_ring;
-			/**< mac ring configuration */
+			/**< MAC (Media Access Point) ring configuration. */
 	uint32_t radio_id;
-			/**< mac radio id */
+			/**< MAC radio ID. */
 	uint32_t hwmode;
-			/**< mac hw mode */
+			/**< MAC hardware mode. */
 };
 
 /**
  * nss_wifili_peer_msg
- *	wifili peer create message.
+ *	Wifili peer creation message.
  */
 struct nss_wifili_peer_msg {
 	uint8_t peer_mac_addr[6];
-			/**< peer mac address */
+			/**< Peer MAC address. */
 	uint16_t vdev_id;
-			/**< vap id */
+			/**< VAP ID. */
 	uint16_t peer_id;
-			/**< peer id */
+			/**< Peer ID. */
 	uint16_t hw_ast_idx;
-			/**< hw address search table index */
+			/**< Hardware address search table index. */
 	uint8_t is_nawds;
-			/**< is NAWDS enabled for peer */
+			/**< NAWDS enabled for peer. */
 };
 
 /**
  * nss_wifili_peer_freelist_append_msg
- *	peer memory request
+ *	Peer memory request.
  */
 struct nss_wifili_peer_freelist_append_msg {
 	uint32_t addr;
-			/**< starting address of peer_freelist pool */
+			/**< Starting address of peer_freelist pool. */
 	uint32_t length;
-			/**< length of peer_freelist pool */
+			/**< Length of peer freelist pool. */
 	uint32_t num_peers;
-			/**< max number of peer entries supported in pool */
+			/**< Maximum number of peer entries supported in pool. */
 };
 
 /**
  * nss_wifili_tx_stats
- *	tx statistics
+ *	Tx statistics.
  */
 struct nss_wifili_tx_stats {
 	uint32_t tx_enqueue_dropped;
-			/**< tx enqueue drop count */
+			/**< Tx enqueue drop count. */
 	uint32_t tx_enqueue_cnt;
-			/**< tx enqueue succesful count */
+			/**< Tx enqueue succesful count. */
 	uint32_t tx_dequeue_cnt;
-			/**< tx dequeue count */
+			/**< Tx dequeue count. */
 	uint32_t tx_send_fail_cnt;
-			/**< hw send fail count */
+			/**< Hardware send failure count. */
 	uint32_t inv_peer;
-			/**< invalid peer enqueue count */
+			/**< Invalid peer enqueue count. */
 	uint32_t inv_peer_drop_byte_cnt;
-			/**< invalid peer drop byte count */
+			/**< Invalid peer drop byte count. */
 	uint32_t tx_input_pkt;
-			/**< tx packets ready to sent */
+			/**< Tx packets ready to sent. */
 	uint32_t tx_processed_pkt;
-			/**< tx no of packets sent */
+			/**< Tx numner of packets sent. */
 	uint32_t tx_processed_bytes;
-			/**< tx no of bytes processed */
+			/**< Tx number of bytes processed. */
 
 };
 
-/*
+/**
  * nss_wifili_rx_stats
- *	rx statistics
+ *	Rx statistics.
  */
 struct nss_wifili_rx_stats {
 	uint32_t rx_msdu_err;
-					/**< rx msdu error count */
+					/**< Rx msdu error count. */
 	uint32_t rx_inv_peer;
-					/**< rx invalid peer count */
+					/**< Rx invalid peer count. */
 	uint32_t rx_scatter_inv_peer;
-					/**< rx scatter invalid peer count */
+					/**< Rx scatter invalid peer count. */
 	uint32_t rx_wds_learn_send;
-					/**< wds src port learn packet */
+					/**< WDS source port learn packet. */
 	uint32_t rx_wds_learn_send_fail;
-					/**< wds src port learn exception send fail cnt */
+					/**< WDS source port learn exception send failure count. */
 	uint32_t rx_send_dropped;
-					/**< rx send dropped count */
+					/**< Rx send dropped count. */
 	uint32_t rx_deliver_cnt;
-					/**< rx deliver count to next node */
+					/**< Rx deliver count to next node. */
 	uint32_t rx_deliver_cnt_fail;
-					/**< rx deliver count fail*/
+					/**< Rx deliver count failure. */
 	uint32_t rx_intra_bss_ucast_send;
-					/**< intrabss unicast sent count */
+					/**< Intra-BSS unicast sent count. */
 	uint32_t rx_intra_bss_ucast_send_fail;
-					/**< intrabss unicast send fail count */
+					/**< Intra-BSS unicast send failure count. */
 	uint32_t rx_intra_bss_mcast_send;
-					/**< intrabss mcast send count */
+					/**< Intra-BSS mcast send count. */
 	uint32_t rx_intra_bss_mcast_send_fail;
-					/**< intrabss mcast send fail count */
+					/**< Intra-BSS mcast send failure count. */
 	uint32_t rx_sg_recv_send;
-					/**< rx sg receive send count */
+					/**< Rx scatter-gather receive send count. */
 	uint32_t rx_sg_recv_fail;
-					/**< rx sg receive fail count */
+					/**< Rx scatter-gather receive failure count. */
 };
 
 /**
  * nss_wifili_tx_tcl_ring_stats
- *	tcl ring specific statistics;
+ *	Transmit Classifier ring specific statistics.
  */
 struct nss_wifili_tx_tcl_ring_stats {
-	uint32_t tcl_no_hw_desc;	/**< no of tcl hw descriptors*/
-	uint32_t tcl_ring_full;		/**< no of times tcl ring full*/
-	uint32_t tcl_ring_sent;		/**< totall no of ring sent*/
+	uint32_t tcl_no_hw_desc;	/**< Number of Transmit Classifier hardware descriptors. */
+	uint32_t tcl_ring_full;		/**< Number of times Transmit Classifier ring full. */
+	uint32_t tcl_ring_sent;		/**< Total number of ring sent. */
 };
 
 /**
  * nss_wifili_tx_comp_ring_stats
- *	Tx completion ring statistics
+ *	Tx completion ring statistics.
  */
 struct nss_wifili_tx_comp_ring_stats {
-	uint32_t invalid_bufsrc;	/**< tx comp ring desc invalid bufsrc */
-	uint32_t invalid_cookie;	/**< tx com ring desc invalid cookie  */
-	uint32_t hw_ring_empty;		/**< tx comp no comp ring available */
-	uint32_t ring_reaped;		/**< tx comp successfull ring reaped*/
+	uint32_t invalid_bufsrc;	/**< Tx comp (Completion) ring descriptor invalid buffer source. */
+	uint32_t invalid_cookie;	/**< Tx comletion ring descriptor has invalid cookies. */
+	uint32_t hw_ring_empty;		/**< Tx completion hardware ring empty. */
+	uint32_t ring_reaped;		/**< Tx completion successfull ring reaped. */
 
 };
 
 /**
  * nss_wifili_tx_sw_pool_stats
- *	Tx completion sw stats
+ *	Tx completion sw statistics.
  */
 struct nss_wifili_tx_sw_pool_stats {
-	uint32_t desc_alloc;			/**< tx desc sw pool desc in use*/
-	uint32_t desc_alloc_fail;		/**< tx desc sw pool alloc fail  */
-	uint32_t desc_already_allocated;	/**< tx desc re-alloc for allocated desc */
-	uint32_t desc_invalid_free;		/**< tx desc freeing of allocated desc */
-	uint32_t tx_rel_src_fw;			/**< tx desc src is fw */
-	uint32_t tx_rel_ext_desc;		/**< tx desc sg */
-	uint32_t tx_rel_tx_desc;		/**< tx desc src is hw*/
-	uint32_t tx_rel_no_pb;			/**< tx desc has pbuf present */
+	uint32_t desc_alloc;			/**< Tx descriptor software pool descriptor in use. */
+	uint32_t desc_alloc_fail;		/**< Tx descriptor software pool allocation failure . */
+	uint32_t desc_already_allocated;	/**< Tx descriptor re-allocation for allocated descriptor. */
+	uint32_t desc_invalid_free;		/**< Tx descriptor freeing of allocated descriptor. */
+	uint32_t tx_rel_src_fw;			/**< Tx descriptor source is firmware. */
+	uint32_t tx_rel_ext_desc;		/**< Tx descriptor scatter-gather. */
+	uint32_t tx_rel_tx_desc;		/**< Tx descriptor source is hardware*/
+	uint32_t tx_rel_no_pb;			/**< Tx descriptor has pbuf present. */
 };
 
-/*
+/**
  * wifili_tx_ext_sw_pool_stats
- *	Tx ext desc pool
+ *	Tx extended descriptor pool.
  */
 struct nss_wifili_tx_ext_sw_pool_stats {
-	uint32_t desc_alloc;			/**< tx ext(sg) desc in use */
-	uint32_t desc_alloc_fail;		/**< tx ext desc alloc fail */
-	uint32_t desc_already_allocated;	/**< tx ext desc already allocated */
-	uint32_t desc_invalid_free;		/**< tx desc invalid src */
+	uint32_t desc_alloc;			/**< Tx extend (scatter gather) descriptor in use. */
+	uint32_t desc_alloc_fail;		/**< Tx extend descriptor allocation failure. */
+	uint32_t desc_already_allocated;	/**< Tx extend descriptor already allocated. */
+	uint32_t desc_invalid_free;		/**< Tx descriptor invalid source. */
 
 };
 
 /**
  * nss_wifili_rx_wbm_ring_stats
- *	wbm release ring statistics
+ *	WBM (Wireless Buffer Manager) release ring statistics.
  */
 struct nss_wifili_rx_wbm_ring_stats {
-	uint32_t invalid_buf_mgr;		/**< wbm invalid buffer manager */
-	uint32_t err_src_rxdma;			/**< wbm src is rdma ring */
-	uint32_t err_src_rxdma_code_inv;	/**< wbm src dma reason unknown */
-	uint32_t err_src_reo;			/**< wbm src is reo */
-	uint32_t err_src_reo_code_nullq;	/**< wbm src reo because of null tlv */
-	uint32_t err_src_reo_code_inv;		/**< wbm src reo reason unknown */
-	uint32_t err_src_invalid;		/**< wbm src is unknown */
+	uint32_t invalid_buf_mgr;		/**< Invalid buffer manager. */
+	uint32_t err_src_rxdma;			/**< WBM source is rdma ring. */
+	uint32_t err_src_rxdma_code_inv;	/**< WBM source DMA reason unknown. */
+	uint32_t err_src_reo;			/**< WBM source is reorder ring. */
+	uint32_t err_src_reo_code_nullq;	/**< WBM source reorder ring because of null tlv. */
+	uint32_t err_src_reo_code_inv;		/**< WBM source reorder ring reason unknown. */
+	uint32_t err_src_invalid;		/**< WBM source is unknown. */
 };
 
 /**
  * nss_wifili_rx_reo_ring_stats
- * 	reo error statistics
+ * 	Reorder error statistics.
  */
 struct nss_wifili_rx_reo_ring_stats {
-	uint32_t ring_error;			/**< reo ring error*/
-	uint32_t ring_reaped;			/**< no of ring desc reaped */
-	uint32_t invalid_cookie;		/**< no of invalid cookie */
+	uint32_t ring_error;			/**< Reorder ring error. */
+	uint32_t ring_reaped;			/**< Number of ring descriptor reaped. */
+	uint32_t invalid_cookie;		/**< Number of invalid cookie. */
 };
 
 /**
  * nss_wifili_rx sw_pool_stats
- *	nss_wifoli dma sw pool stats
+ *	Wifili DMA sw pool statistics.
  */
 struct nss_wifili_rx_sw_pool_stats {
-	uint32_t rx_no_pb;			/**< rx sw  desc no buff avail */
-	uint32_t desc_alloc;			/**< no of desc in use */
-	uint32_t desc_alloc_fail;		/**< no of desc alloc fail */
+	uint32_t rx_no_pb;			/**< Rx software descriptor number of buffer available. */
+	uint32_t desc_alloc;			/**< Number of descriptor in use. */
+	uint32_t desc_alloc_fail;		/**< Number of descriptor allocation failure. */
 };
 
-/*
- * wifili rx dma ring stats
- *	nss_wifli dma ring statistics
+/**
+ * nss_wifili_rx_dma_ring_stats
+ *	Wifili Rx DMA ring statistics.
  */
 struct nss_wifili_rx_dma_ring_stats {
-	uint32_t rx_hw_desc_unavailable;	/**< no of times hw desc is unavailable */
+	uint32_t rx_hw_desc_unavailable;	/**< Number of times hardware descriptor is unavailable. */
 };
 
 /**
  * nss_wifili_device_stats
- * 	wifili device specific stats
+ * 	Wifili specific statistics.
  */
 struct nss_wifili_device_stats {
 	struct nss_wifili_tx_tcl_ring_stats tcl_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
-									/**< tcl ring stats */
+									/**< Transmit Classifier ring statistics. */
 	struct nss_wifili_tx_comp_ring_stats txcomp_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG];
-									/**< tx comp ring stats*/
+									/**< Tx completion ring stats. */
 	struct nss_wifili_tx_sw_pool_stats tx_sw_pool_stats[NSS_WIFILI_MAX_TXDESC_POOLS_MSG];
-									/**< tx sw pool stats */
+									/**< Tx software pool statistics. */
 	struct nss_wifili_tx_ext_sw_pool_stats tx_ext_sw_pool_stats[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG];
-									/**< tx ext ext sw pool stats */
+									/**< Tx extended software pool statistics. */
 	struct nss_wifili_tx_stats tx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
-									/**< tx data stats for each pdev */
+									/**< Tx data statistics for each pdev. */
 	struct nss_wifili_rx_reo_ring_stats rxreo_stats[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG];
-									/**< rx reo ring stats */
+									/**< Rx reorder ring statistics. */
 	struct nss_wifili_rx_sw_pool_stats rx_sw_pool_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
-									/**< rx dma sw pool stats */
+									/**< Rx DMA software pool statistics. */
 	struct nss_wifili_rx_stats rx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
-									/**< rx data stats for each pdev */
+									/**< Rx data statistics for each pdev. */
 	struct nss_wifili_rx_dma_ring_stats rxdma_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG];
-									/**< rx dma ring stats */
+									/**< Rx DMA ring statistics. */
 	struct nss_wifili_rx_wbm_ring_stats rxwbm_stats;
-									/**< wbm ring stats */
+									/**< WBM ring statistics. */
 };
 
 /**
  * nss_wifili_stats_sync_msg
- *	li stats sync msg
+ *	Wifili SoC statistics synchronization message.
  */
 struct nss_wifili_stats_sync_msg {
 	struct nss_wifili_device_stats stats;
-			/**< device statistics */
+			/**< Device statistics. */
 };
 
 /**
- * wifili_soc_linkdesc_per_packet_metadata
- *	linkdesc per packet metadata
+ * nss_wifili_soc_linkdesc_per_packet_metadata
+ *	Link descriptor per packet metadata.
  */
-struct wifili_soc_linkdesc_per_packet_metadata
+struct nss_wifili_soc_linkdesc_per_packet_metadata
 {
-	uint32_t desc_addr;	/**< link descriptor address */
+	uint32_t desc_addr;	/**< Link descriptor address. */
 };
 
 /**
- * wifili_soc_per_packet_metadata
- *	Per packet special data that has to be sent to host
+ * nss_wifili_soc_per_packet_metadata
+ *	Per packet special data that has to be sent to host.
  */
-struct wifili_soc_per_packet_metadata {
+struct nss_wifili_soc_per_packet_metadata {
 	uint32_t pkt_type;
 	union {
-		struct wifili_soc_linkdesc_per_packet_metadata linkdesc_metadata;
+		struct nss_wifili_soc_linkdesc_per_packet_metadata linkdesc_metadata;
 	} metadata;
 };
 
 /**
+ * nss_wifili_tx_mcs
+ *	Peer MCS count.
+ */
+struct nss_wifili_tx_mcs {
+	uint32_t mcs_count[NSS_WIFILI_MAX_MCS + 1];	/**< MCS count. */
+};
+
+/**
+ * Packets dropped on the Tx side
+ *	Tx peer dropped packets.
+ */
+struct nss_wifili_tx_dropped {
+	uint32_t dma_map_error;		/**< Discarded by firmware. */
+	uint32_t ring_full;		/**< Dropped due to ring full. */
+	uint32_t fw_discard;		/**< Discarded by firmware. */
+	uint32_t fw_discard_retired;	/**< Firmware discard retired. */
+	uint32_t fw_discard_untransmitted;	/**< Firmware discard untransmitted. */
+	uint32_t mpdu_age_out;		/**< Number of PDU aged out. */
+	uint32_t fw_discard_reason1;	/**< Firmware discarded PDU reason 1. */
+	uint32_t fw_discard_reason2;	/**< Firmware discarded PDU reason 2. */
+	uint32_t fw_discard_reason3;	/**< Firmware discarded PDU reason 3. */
+};
+
+/**
+ * nss_wifili_tx_ctrl_stats
+ *	Tx peer statistics.
+ */
+struct nss_wifili_tx_ctrl_stats {
+	uint32_t tx_failed; 		/**< Total Tx failure. */
+	uint32_t ofdma; 		/**< Total number of OFDMA packets. */
+	uint32_t stbc; 			/**< Packets in STBC. */
+	uint32_t ldpc; 			/**< Packets in LDPC. */
+	uint32_t retries; 		/**< Packet retries. */
+	uint32_t non_amsdu_cnt; 	/**< Number of MSDUs with no MSDU level aggregation. */
+	uint32_t amsdu_cnt;		/**< Number of MSDUs part of AMSDU. */
+	uint32_t last_ack_rssi; 	/**< RSSI of last packet. */
+
+	struct nss_wifili_tx_mcs pkt_type[NSS_WIFILI_DOT11_MAX];	/**< MCS count. */
+	uint32_t sgi_count[NSS_WIFILI_MAX_MCS + 1]; 	/**< SGI count. */
+	uint32_t bw[NSS_WIFILI_SUPPORTED_BW];		/**< Packet Count for different bandwidths. */
+	uint32_t wme_ac_type[NSS_WIFILI_WME_AC_MAX]; 	/**< Wireless Multimedia type Count. */
+	uint32_t excess_retries_ac[NSS_WIFILI_WME_AC_MAX];	/**< Wireless Multimedia type Count. */
+	struct nss_wifili_tx_dropped dropped;	/**< Tx peer dropped. */
+	uint32_t complete_pkt;		/**< Complete packet count. */
+	uint32_t complete_byte;		/**< Complete byte count. */
+	uint32_t failed;		/**< Failed packet count. */
+	uint32_t success;		/**< Success packet count. */
+	uint32_t success_bytes;		/**< Success bytes count. */
+};
+
+/**
+ * nss_wifili_peer_rx_err
+ *	Rx peer errors.
+ */
+struct nss_wifili_rx_err {
+	uint32_t mic_err;	/**< Rx MIC errors. */
+	uint32_t decrypt_err;	/**< Rx Decryption errors. */
+};
+
+/**
+ * nss_wifili_rx_ctrl_stats
+ *	Peer Rx statistics.
+ */
+struct nss_wifili_rx_ctrl_stats {
+	struct nss_wifili_rx_err err;			/**< Rx peer errors. */
+	uint32_t wme_ac_type[NSS_WIFILI_WME_AC_MAX];	/**< Wireless Multimedia type Count. */
+	uint32_t reception_type[NSS_WIFILI_SUPPORTED_RECEPTION_TYPES];	/**< Reception type OS packets. */
+	uint32_t mcs_count[NSS_WIFILI_MAX_MCS + 1];	/**< Packets in different MCS rates. */
+	uint32_t sgi_count[NSS_WIFILI_MAX_MCS + 1];	/**< SGI count. */
+	uint32_t nss[NSS_WIFILI_SS_COUNT];		/**< Packet count in spatiel Streams. */
+	uint32_t bw[NSS_WIFILI_SUPPORTED_BW];		/**< Packet Count in different bandwidths. */
+	uint32_t non_ampdu_cnt;			/**< Number of MSDUs with no MPDU level aggregation. */
+	uint32_t ampdu_cnt;			/**< Number of MSDUs part of AMPDU. */
+	uint32_t non_amsdu_cnt;			/**< Number of MSDUs with no MSDU level aggregation. */
+	uint32_t amsdu_cnt;			/**< Number of MSDUs part of AMSDU. */
+	uint32_t mcast_rcv_cnt;			/**< Total number of mcast packets received. */
+	uint32_t ucast_rcv_cnt;			/**< Unicast received count. */
+	uint32_t rx_recvd;			/**< Total Rx received count. */
+};
+
+/**
+ * nss_wifili_peer_ctrl_stats
+ *	Wifili peer control statistics.
+ */
+struct nss_wifili_peer_ctrl_stats {
+	uint32_t peer_id;	/**< Peer ID. */
+	struct nss_wifili_tx_ctrl_stats tx;
+				/**< Peer Tx control statistics. */
+	struct nss_wifili_rx_ctrl_stats rx;
+				/**< Peer Rx control statistics. */
+};
+
+/**
+ * nss_wifili peer stats
+ *	Wifili peer statistics.
+ */
+struct nss_wifili_peer_stats {
+	uint32_t npeers;	/**< Number of entries of peer statistics. */
+	struct nss_wifili_peer_ctrl_stats wpcs[1];
+				/**< Wifili peer control statistics. */
+};
+
+/**
+ * wifili_peer_stats_msg
+ *	Wifili peer statistics message.
+ */
+struct nss_wifili_peer_stats_msg {
+	struct nss_wifili_peer_stats stats;
+			/**< Wifili peer statistics. */
+};
+
+
+/**
  * nss_wifili_msg
- *	Structure that describes wifi li messages
+ *	Structure that describes wifili messages.
  */
 struct nss_wifili_msg {
-	struct nss_cmn_msg cm;                  /**< Common message Header */
+	struct nss_cmn_msg cm;                  /**< Common message header. */
 	union {
 		struct nss_wifili_init_msg init;
 				/**< Wi-Fi initialization data. */
@@ -516,19 +678,21 @@
 				/**< Information for creating a peer freelist. */
 		struct nss_wifili_stats_sync_msg wlsoc_stats;
 				/**< Synchronization statistics. */
+		struct nss_wifili_peer_stats_msg peer_stats;
+				/**< Wifili peer statistics. */
 	} msg;
 };
 
 /**
  * nss_wifili_tx_msg
- *	Send wifili messages
+ *	Send wifili messages.
  *
  * @datatypes
  * nss_ctx_instance \n
  * nss_wifili_msg
  *
  * @param[in] nss_ctx NSS context.
- * @param[in] msg     NSS wifi message.
+ * @param[in] msg     NSS Wi-Fi message.
  *
  * @return
  * nss_tx_status_t Tx status
@@ -537,7 +701,7 @@
 
 /**
  * nss_wifili_msg_callback_t
- *	Callback to receive wifili messages
+ *	Callback to receive wifili messages.
  *
  * @datatypes
  * nss_wifili_msg
@@ -552,7 +716,7 @@
 
 /**
  * nss_wifili_callback_t
- *	Callback to receive wifi data
+ *	Callback to receive Wi-Fi data.
  *
  * @datatypes
  * net_device \n
@@ -571,7 +735,7 @@
 
 /**
  * nss_register_wifili_if
- *	Register to send/receive wifi li soc messages to NSS
+ *	Register to send/receive wifili SoC messages to NSS.
  *
  * @datatypes
  * nss_wifili_callback_t \n
@@ -594,7 +758,7 @@
 
 /**
  * nss_unregister_wifili_if
- *	Unregister wifi li soc interface with NSS
+ *	Deregister wifili SoC interface with NSS.
  *
  * @param[in] if_num NSS interface number
  *
@@ -605,7 +769,7 @@
 
 /**
  * nss_register_wifili_radio_if
- *	Register to send/receive wifi li radio messages to NSS
+ *	Register to send/receive wifili radio messages to NSS.
  *
  * @datatypes
  * nss_wifili_callback_t \n
@@ -628,7 +792,7 @@
 
 /**
  * nss_unregister_wifili_radio_if
- *	Unregister wifi li radio interface with NSS
+ *	Deregister wifili radio interface with NSS.
  *
  * @param[in] if_num NSS interface number
  *
diff --git a/nss_bridge.c b/nss_bridge.c
index 88b5d73..8c465b7 100644
--- a/nss_bridge.c
+++ b/nss_bridge.c
@@ -82,6 +82,15 @@
 }
 
 /*
+ * nss_bridge_get_context()
+ */
+struct nss_ctx_instance *nss_bridge_get_context(void)
+{
+	return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.bridge_handler_id];
+}
+EXPORT_SYMBOL(nss_bridge_get_context);
+
+/*
  * nss_bridge_verify_if_num()
  *	Verify if_num passed to us.
  */
@@ -91,7 +100,7 @@
 		return false;
 	}
 
-	if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) {
+	if (nss_dynamic_interface_get_type(nss_bridge_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) {
 		return false;
 	}
 
@@ -221,15 +230,6 @@
 EXPORT_SYMBOL(nss_bridge_tx_msg_sync);
 
 /*
- * nss_bridge_get_context()
- */
-struct nss_ctx_instance *nss_bridge_get_context(void)
-{
-	return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.bridge_handler_id];
-}
-EXPORT_SYMBOL(nss_bridge_get_context);
-
-/*
  * nss_bridge_msg_init()
  *	Initialize nss_bridge_msg.
  */
diff --git a/nss_capwap.c b/nss_capwap.c
index 13df093..3c0af95 100644
--- a/nss_capwap.c
+++ b/nss_capwap.c
@@ -55,7 +55,7 @@
 		return false;
 	}
 
-	if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
+	if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
 		return false;
 	}
 
diff --git a/nss_cmn.c b/nss_cmn.c
index 9c2b108..44dc27b 100644
--- a/nss_cmn.c
+++ b/nss_cmn.c
@@ -156,11 +156,11 @@
  * nss_cmn_interface_is_virtual()
  * 	Return true if the interface number is a virtual NSS interface
  */
-bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num)
+bool nss_cmn_interface_is_virtual(struct nss_ctx_instance *nss_ctx, int32_t interface_num)
 {
-	return ((nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
-		|| (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
-		|| (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED));
+	return (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
+		|| (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
+		|| (nss_dynamic_interface_get_type(nss_ctx, interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED);
 }
 
 /*
diff --git a/nss_core.c b/nss_core.c
index 2395be1..89672a0 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -56,11 +56,25 @@
 module_param(max_ipv6_conn, int, S_IRUGO);
 MODULE_PARM_DESC(max_ipv6_conn, "Max number of IPv6 connections");
 
+static bool pn_mq_en = false;
+module_param(pn_mq_en, bool, S_IRUGO);
+MODULE_PARM_DESC(pn_mq_en, "Enable pnode ingress Qos");
+
+static int pn_pri_num = NSS_MAX_NUM_PRI;
+module_param(pn_pri_num, int, S_IRUGO);
+MODULE_PARM_DESC(pn_pri_num, "Maximum number of queue priority");
+
+static int pn_qlimits[NSS_MAX_NUM_PRI] = { NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT,
+					       NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT};
+module_param_array(pn_qlimits, int, NULL, 0);
+MODULE_PARM_DESC(pn_qlimits, "Default queue limit");
+
 /*
  * Track IPv4/IPv6 max connection update done
  */
 static int max_ipv4_conn_update_done;
 static int max_ipv6_conn_update_done;
+static int pn_q_update_done;
 
 /*
  * Atomic variables to control jumbo_mru & paged_mode
@@ -1221,6 +1235,7 @@
 	int32_t i;
 	struct nss_top_instance *nss_top;
 	bool is_scheduled = true;
+	int ret;
 
 	/*
 	 * NOTE: A commonly found error is that sizes and start address of per core
@@ -1264,6 +1279,17 @@
 	}
 
 	if (is_scheduled) {
+
+		/*
+		 * Send pnode queue config message
+		 */
+		if (pn_q_update_done == 0) {
+			ret = nss_n2h_update_queue_config(nss_top->num_pri, pn_mq_en, pn_pri_num, pn_qlimits);
+			if (ret == NSS_TX_SUCCESS) {
+				pn_q_update_done = 1;
+			}
+		}
+
 		/*
 		 * Configure the maximum number of IPv4/IPv6
 		 * connections supported by the accelerator.
@@ -1577,16 +1603,9 @@
 		return NSS_N2H_INTR_DATA_QUEUE_3;
 	}
 
-	if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE_0) {
-		printk("NSS core 0 signal COREDUMP COMPLETE %x ", cause);
+	if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE) {
 		*type = NSS_INTR_CAUSE_EMERGENCY;
-		return NSS_N2H_INTR_COREDUMP_COMPLETE_0;
-	}
-
-	if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE_1) {
-		printk("NSS core 1 signal COREDUMP COMPLETE %x\n", cause);
-		*type = NSS_INTR_CAUSE_EMERGENCY;
-		return NSS_N2H_INTR_COREDUMP_COMPLETE_1;
+		return NSS_N2H_INTR_COREDUMP_COMPLETE;
 	}
 
 	return 0;
@@ -1648,6 +1667,8 @@
 				break;
 
 			case NSS_INTR_CAUSE_EMERGENCY:
+				nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n",
+					nss_ctx->id, int_ctx->cause);
 				nss_fw_coredump_notify(nss_ctx, prio_cause);
 				int_ctx->cause &= ~prio_cause;
 				break;
@@ -1677,6 +1698,22 @@
 }
 
 /*
+ * nss_core_handle_napi_emergency()
+ *	NAPI handler for NSS crash
+ */
+int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget)
+{
+	struct netdev_priv_instance *ndev_priv = netdev_priv(napi->dev);
+	struct int_ctx_instance *int_ctx = ndev_priv->int_ctx;
+
+	nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n",
+				int_ctx->nss_ctx->id, int_ctx->cause);
+	nss_fw_coredump_notify(int_ctx->nss_ctx, 0);
+
+	return 0;
+}
+
+/*
  * nss_core_handle_napi_queue()
  *	NAPI handler for NSS queue cause
  */
diff --git a/nss_core.h b/nss_core.h
index 1871f89..2608bca 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -163,7 +163,7 @@
  */
 #if defined(NSS_HAL_IPQ807x_SUPPORT)
 #define NSS_MAX_IRQ_PER_INSTANCE 4
-#define NSS_MAX_IRQ_PER_CORE 7
+#define NSS_MAX_IRQ_PER_CORE 8
 #else
 #define NSS_MAX_IRQ_PER_INSTANCE 1
 #define NSS_MAX_IRQ_PER_CORE 2
@@ -201,6 +201,10 @@
 #define NSS_FREQ_110_MIN	0x03000		/* Instructions Per ms Min */
 #define NSS_FREQ_110_MAX	0x07000		/* Instructions Per ms Max */
 
+#define NSS_FREQ_187		187200000	/* Frequency in hz */
+#define NSS_FREQ_187_MIN	0x03000		/* Instructions Per ms Min */
+#define NSS_FREQ_187_MAX	0x07000		/* Instructions Per ms Max */
+
 #define NSS_FREQ_275		275000000	/* Frequency in hz */
 #define NSS_FREQ_275_MIN	0x03000		/* Instructions Per ms Min */
 #define NSS_FREQ_275_MAX	0x07000		/* Instructions Per ms Max */
@@ -217,10 +221,22 @@
 #define NSS_FREQ_733_MIN	0x07000		/* Instructions Per ms Min */
 #define NSS_FREQ_733_MAX	0x25000		/* Instructions Per ms Max */
 
+#define NSS_FREQ_748		748800000	/* Frequency in hz */
+#define NSS_FREQ_748_MIN	0x07000		/* Instructions Per ms Min */
+#define NSS_FREQ_748_MAX	0x10000		/* Instructions Per ms Max */
+
 #define NSS_FREQ_800		800000000	/* Frequency in hz */
 #define NSS_FREQ_800_MIN	0x07000		/* Instructions Per ms Min */
 #define NSS_FREQ_800_MAX	0x25000		/* Instructions Per ms Max */
 
+#define NSS_FREQ_1497		1497600000	/* Frequency in hz */
+#define NSS_FREQ_1497_MIN	0x10000		/* Instructions Per ms Min */
+#define NSS_FREQ_1497_MAX	0x25000		/* Instructions Per ms Max */
+
+#define NSS_FREQ_1689		1689600000	/* Frequency in hz */
+#define NSS_FREQ_1689_MIN	0x10000		/* Instructions Per ms Min */
+#define NSS_FREQ_1689_MAX	0x25000		/* Instructions Per ms Max */
+
 #if (NSS_DT_SUPPORT == 1)
 #define NSSTCM_FREQ		400000000	/* NSS TCM Frequency in Hz */
 
@@ -1294,6 +1310,7 @@
 	NSS_EDMA_PKT_LEN_LA64K_ERR,
 	NSS_EDMA_PKT_LEN_LE33_ERR,
 	NSS_EDMA_DATA_LEN_ERR,
+	NSS_EDMA_ALLOC_FAIL_CNT,
 	NSS_EDMA_ERR_STATS_MAX
 };
 
@@ -1512,6 +1529,7 @@
 struct nss_top_instance {
 	uint8_t num_nss;			/* Number of NSS cores supported */
 	uint8_t num_phys_ports;			/* Number of physical ports supported */
+	uint8_t num_pri;			/* Maximum number of priority */
 	uint32_t clk_src;			/* Clock source: default/alternate */
 	spinlock_t lock;			/* Big lock for NSS driver */
 	spinlock_t stats_lock;			/* Statistics lock */
@@ -1835,6 +1853,7 @@
 	uint32_t id;				/* NSS core ID */
 	uint32_t num_queue;			/* No. of queues supported per core */
 	uint32_t num_irq;			/* No. of irq binded per queue */
+	uint8_t num_pri;			/* Maximum number of priority supported. */
 	uint32_t irq[NSS_MAX_IRQ_PER_CORE];	/* IRQ numbers per queue */
 	void __iomem *nmap;			/* Virtual addr of NSS CSM space */
 	void __iomem *vmap;			/* Virtual addr of NSS virtual register map */
@@ -1933,6 +1952,7 @@
 extern int nss_core_handle_napi(struct napi_struct *napi, int budget);
 extern int nss_core_handle_napi_queue(struct napi_struct *napi, int budget);
 extern int nss_core_handle_napi_non_queue(struct napi_struct *napi, int budget);
+extern int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget);
 extern int32_t nss_core_send_buffer(struct nss_ctx_instance *nss_ctx, uint32_t if_num,
 					struct sk_buff *nbuf, uint16_t qid,
 					uint8_t buffer_type, uint16_t flags);
diff --git a/nss_dtls.c b/nss_dtls.c
index f526224..c26b730 100644
--- a/nss_dtls.c
+++ b/nss_dtls.c
@@ -36,7 +36,6 @@
 	void *app_data;
 } dtls_pvt;
 
-
 /*
  * nss_dtls_verify_if_num()
  *	Verify if_num passed to us.
@@ -46,7 +45,7 @@
 	if (nss_is_dynamic_interface(if_num) == false)
 		return false;
 
-	if (nss_dynamic_interface_get_type(if_num)
+	if (nss_dynamic_interface_get_type(nss_dtls_get_context(), if_num)
 	    != NSS_DYNAMIC_INTERFACE_TYPE_DTLS)
 		return false;
 
diff --git a/nss_dynamic_interface.c b/nss_dynamic_interface.c
index fdcb80d..5f3ae90 100644
--- a/nss_dynamic_interface.c
+++ b/nss_dynamic_interface.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, 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.
@@ -18,7 +18,16 @@
 
 #define NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT 60000	/* 60 Sec */
 
-static struct nss_dynamic_interface_pvt di;
+/*
+ * Message data structure to store the message result
+ */
+struct nss_dynamic_interface_msg_data {
+	struct completion complete;	/* completion structure */
+	int if_num;			/* Interface number */
+	enum nss_cmn_response response;	/* Message response */
+};
+
+static nss_dynamic_interface_assigned nss_dynamic_interface_assigned_types[NSS_CORE_MAX][NSS_MAX_DYNAMIC_INTERFACES]; /* Array of assigned interface types */
 
 /*
  * nss_dynamic_interface_handler()
@@ -57,10 +66,9 @@
 	case NSS_DYNAMIC_INTERFACE_ALLOC_NODE:
 		if (ncm->response == NSS_CMN_RESPONSE_ACK) {
 			nss_info("%p alloc_node response ack if_num %d\n", nss_ctx, ndim->msg.alloc_node.if_num);
-			di.current_if_num = ndim->msg.alloc_node.if_num;
-			if_num = di.current_if_num;
+			if_num = ndim->msg.alloc_node.if_num;
 			if (if_num > 0) {
-				di.type[if_num - NSS_DYNAMIC_IF_START] = ndim->msg.alloc_node.type;
+				nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = ndim->msg.alloc_node.type;
 			} else {
 				nss_warning("%p: if_num < 0\n", nss_ctx);
 			}
@@ -71,9 +79,8 @@
 	case NSS_DYNAMIC_INTERFACE_DEALLOC_NODE:
 		if (ncm->response == NSS_CMN_RESPONSE_ACK) {
 			nss_info("%p dealloc_node response ack if_num %d\n", nss_ctx, ndim->msg.dealloc_node.if_num);
-			di.current_if_num = ndim->msg.dealloc_node.if_num;
-			if_num = di.current_if_num;
-			di.type[if_num - NSS_DYNAMIC_IF_START] = NSS_DYNAMIC_INTERFACE_TYPE_NONE;
+			if_num = ndim->msg.dealloc_node.if_num;
+			nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = NSS_DYNAMIC_INTERFACE_TYPE_NONE;
 		}
 
 		break;
@@ -105,52 +112,16 @@
  */
 static void nss_dynamic_interface_callback(void *app_data, struct nss_cmn_msg *ncm)
 {
+	struct nss_dynamic_interface_msg_data *di_data = (struct nss_dynamic_interface_msg_data *)app_data;
+	struct nss_dynamic_interface_msg *ndim = (struct nss_dynamic_interface_msg *)ncm;
+
+	di_data->response = ncm->response;
+	di_data->if_num = ndim->msg.alloc_node.if_num;
+
 	/*
 	 * Unblock the sleeping function.
 	 */
-	di.response = ncm->response;
-	complete(&di.complete);
-}
-
-/*
- * nss_dynamic_interface_tx_sync()
- *	Send the message to NSS and wait till we get an ACK or NACK for this msg.
- */
-static nss_tx_status_t nss_dynamic_interface_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg *ndim)
-{
-	nss_tx_status_t status;
-	int ret;
-
-	if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
-		nss_warning("%p: dynamic if msg dropped as core not ready", nss_ctx);
-		return NSS_TX_FAILURE_NOT_READY;
-	}
-
-	/*
-	 * Acquring a semaphore , so that only one caller can send msg at a time.
-	 */
-	down(&di.sem);
-	di.response = false;
-
-	status = nss_dynamic_interface_tx(nss_ctx, ndim);
-	if (status != NSS_TX_SUCCESS) {
-		up(&di.sem);
-		nss_warning("%p: not able to transmit msg successfully\n", nss_ctx);
-		return status;
-	}
-
-	/*
-	 * Blocking call, wait till we get ACK for this msg.
-	 */
-	ret = wait_for_completion_timeout(&di.complete, msecs_to_jiffies(NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT));
-	if (ret == 0) {
-		up(&di.sem);
-		nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
-		return NSS_TX_FAILURE;
-	}
-
-	up(&di.sem);
-	return status;
+	complete(&di_data->complete);
 }
 
 /*
@@ -216,6 +187,34 @@
 }
 
 /*
+ * nss_dynamic_interface_tx_sync()
+ *	Send the message to NSS and wait till we get an ACK or NACK for this msg.
+ */
+static nss_tx_status_t nss_dynamic_interface_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg_data *di_data,
+						     struct nss_dynamic_interface_msg *ndim)
+{
+	nss_tx_status_t status;
+	int ret;
+
+	status = nss_dynamic_interface_tx(nss_ctx, ndim);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: not able to transmit msg successfully\n", nss_ctx);
+		return status;
+	}
+
+	/*
+	 * Blocking call, wait till we get ACK for this msg.
+	 */
+	ret = wait_for_completion_timeout(&di_data->complete, msecs_to_jiffies(NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT));
+	if (ret == 0) {
+		nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+		return NSS_TX_FAILURE;
+	}
+
+	return status;
+}
+
+/*
  * nss_dynamic_interface_alloc_node()
  *	Allocates node of perticular type on NSS and returns interface_num for this node or -1 in case of failure.
  *
@@ -227,6 +226,7 @@
 	struct nss_ctx_instance *nss_ctx = NULL;
 	struct nss_dynamic_interface_msg ndim;
 	struct nss_dynamic_interface_alloc_node_msg *ndia;
+	struct nss_dynamic_interface_msg_data di_data;
 	uint32_t core_id;
 	nss_tx_status_t status;
 
@@ -237,9 +237,12 @@
 
 	core_id = nss_top_main.dynamic_interface_table[type];
 	nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
+	di_data.if_num = -1;
+	di_data.response = false;
+	init_completion(&di_data.complete);
 
 	nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_ALLOC_NODE,
-				sizeof(struct nss_dynamic_interface_alloc_node_msg), nss_dynamic_interface_callback, (void *)nss_ctx);
+				sizeof(struct nss_dynamic_interface_alloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data);
 
 	ndia = &ndim.msg.alloc_node;
 	ndia->type = type;
@@ -253,21 +256,21 @@
 	/*
 	 * Calling synchronous transmit function.
 	 */
-	status = nss_dynamic_interface_tx_sync(nss_ctx, &ndim);
+	status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim);
 	if (status != NSS_TX_SUCCESS) {
 		nss_warning("%p not able to transmit alloc node msg\n", nss_ctx);
 		return -1;
 	}
 
 	/*
-	 * Check di.response and return -1 if its a NACK else proceed.
+	 * Check response and return -1 if its a NACK else proceed.
 	 */
-	if (di.response != NSS_CMN_RESPONSE_ACK) {
-		nss_warning("%p Received NACK from NSS - Response:%d\n", nss_ctx, di.response);
+	if (di_data.response != NSS_CMN_RESPONSE_ACK) {
+		nss_warning("%p Received NACK from NSS - Response:%d\n", nss_ctx, di_data.response);
 		return -1;
 	}
 
-	return di.current_if_num;
+	return di_data.if_num;
 }
 
 /*
@@ -283,6 +286,7 @@
 	struct nss_ctx_instance *nss_ctx = NULL;
 	struct nss_dynamic_interface_msg ndim;
 	struct nss_dynamic_interface_dealloc_node_msg *ndid;
+	struct nss_dynamic_interface_msg_data di_data;
 	uint32_t core_id;
 	nss_tx_status_t status;
 
@@ -293,6 +297,8 @@
 
 	core_id = nss_top_main.dynamic_interface_table[type];
 	nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
+	di_data.response = false;
+	init_completion(&di_data.complete);
 
 	if (nss_is_dynamic_interface(if_num) == false) {
 		nss_warning("%p: nss_dynamic_interface if_num is not in range %d\n", nss_ctx, if_num);
@@ -300,7 +306,7 @@
 	}
 
 	nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_DEALLOC_NODE,
-				sizeof(struct nss_dynamic_interface_dealloc_node_msg), nss_dynamic_interface_callback, (void *)nss_ctx);
+				sizeof(struct nss_dynamic_interface_dealloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data);
 
 	ndid = &ndim.msg.dealloc_node;
 	ndid->type = type;
@@ -309,13 +315,13 @@
 	/*
 	 * Calling synchronous transmit function.
 	 */
-	status = nss_dynamic_interface_tx_sync(nss_ctx, &ndim);
+	status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim);
 	if (status != NSS_TX_SUCCESS) {
 		nss_warning("%p not able to transmit alloc node msg\n", nss_ctx);
 		return status;
 	}
 
-	if (di.response != NSS_CMN_RESPONSE_ACK) {
+	if (di_data.response != NSS_CMN_RESPONSE_ACK) {
 		nss_warning("%p Received NACK from NSS\n", nss_ctx);
 		return -1;
 	}
@@ -329,10 +335,6 @@
 void nss_dynamic_interface_register_handler(struct nss_ctx_instance *nss_ctx)
 {
 	nss_core_register_handler(nss_ctx, NSS_DYNAMIC_INTERFACE, nss_dynamic_interface_handler, NULL);
-
-	sema_init(&di.sem, 1);
-	init_completion(&di.complete);
-	di.current_if_num = -1;
 }
 
 /*
@@ -348,13 +350,13 @@
  * nss_dynamic_interface_get_type()
  *	Gets the type of dynamic interface
  */
-enum nss_dynamic_interface_type nss_dynamic_interface_get_type(int if_num)
+enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num)
 {
 	if (nss_is_dynamic_interface(if_num) == false) {
 		return NSS_DYNAMIC_INTERFACE_TYPE_NONE;
 	}
 
-	return di.type[if_num - NSS_DYNAMIC_IF_START];
+	return nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START];
 }
 
 /*
diff --git a/nss_edma.c b/nss_edma.c
index 7037010..ed63365 100644
--- a/nss_edma.c
+++ b/nss_edma.c
@@ -123,6 +123,7 @@
 	nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LA64K_ERR] += nerss->msg_err_stats.pkt_len_la64k_err;
 	nss_top->stats_edma.misc_err[NSS_EDMA_PKT_LEN_LE33_ERR] += nerss->msg_err_stats.pkt_len_le33_err;
 	nss_top->stats_edma.misc_err[NSS_EDMA_DATA_LEN_ERR] += nerss->msg_err_stats.data_len_err;
+	nss_top->stats_edma.misc_err[NSS_EDMA_ALLOC_FAIL_CNT] += nerss->msg_err_stats.alloc_fail_cnt;
 	spin_unlock_bh(&nss_top->stats_lock);
 }
 
diff --git a/nss_gre_tunnel.c b/nss_gre_tunnel.c
index d8457fb..eea09d5 100644
--- a/nss_gre_tunnel.c
+++ b/nss_gre_tunnel.c
@@ -45,7 +45,7 @@
 	if (nss_is_dynamic_interface(if_num) == false)
 		return false;
 
-	if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL)
+	if (nss_dynamic_interface_get_type(nss_gre_tunnel_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL)
 		return false;
 
 	return true;
diff --git a/nss_hal/fsm9010/nss_hal_pvt.c b/nss_hal/fsm9010/nss_hal_pvt.c
index acb80e2..8b16ed6 100644
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -104,6 +104,10 @@
 		npd->num_irq = nss_hal_get_num_irqs(np);
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	if (npd->num_irq < npd->num_queue) {
 		pr_err("%s: not enough interrupts configured for all the queues\n", np->name);
 		goto out;
diff --git a/nss_hal/include/nss_hal.h b/nss_hal/include/nss_hal.h
index 1ac6e20..ec27362 100644
--- a/nss_hal/include/nss_hal.h
+++ b/nss_hal/include/nss_hal.h
@@ -28,6 +28,7 @@
 #include <nss_hal_ops.h>
 
 extern struct clk *nss_core0_clk;
+extern struct clk *nss_core1_clk;
 extern struct nss_runtime_sampling nss_runtime_samples;
 extern struct clk *nss_fab0_clk;
 extern struct clk *nss_fab1_clk;
@@ -47,8 +48,7 @@
 					NSS_N2H_INTR_DATA_QUEUE_1 | \
 					NSS_N2H_INTR_EMPTY_BUFFERS_SOS | \
 					NSS_N2H_INTR_TX_UNBLOCKED | \
-					NSS_N2H_INTR_COREDUMP_COMPLETE_0 | \
-					NSS_N2H_INTR_COREDUMP_COMPLETE_1)
+					NSS_N2H_INTR_COREDUMP_COMPLETE)
 
 /*
  * nss_hal_read_interrupt_cause()
diff --git a/nss_hal/include/nss_regs.h b/nss_hal/include/nss_regs.h
index 9af9508..e9b1fdf 100644
--- a/nss_hal/include/nss_regs.h
+++ b/nss_hal/include/nss_regs.h
@@ -66,8 +66,7 @@
 #define NSS_N2H_INTR_DATA_QUEUE_3		(1 << 4)
 #define NSS_N2H_INTR_EMPTY_BUFFERS_SOS		(1 << 10)
 #define NSS_N2H_INTR_TX_UNBLOCKED		(1 << 11)
-#define NSS_N2H_INTR_COREDUMP_COMPLETE_1	(1 << 13)
-#define NSS_N2H_INTR_COREDUMP_COMPLETE_0	(1 << 14)
+#define NSS_N2H_INTR_COREDUMP_COMPLETE		(1 << 14)
 
 /*
  * Types of H2N interrupts
diff --git a/nss_hal/ipq806x/nss_hal_pvt.c b/nss_hal/ipq806x/nss_hal_pvt.c
index d325e53..beaa398 100644
--- a/nss_hal/ipq806x/nss_hal_pvt.c
+++ b/nss_hal/ipq806x/nss_hal_pvt.c
@@ -301,6 +301,10 @@
 		goto out;
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	/*
 	 * Read frequencies. If failure, load default values.
 	 */
diff --git a/nss_hal/ipq807x/nss_hal_pvt.c b/nss_hal/ipq807x/nss_hal_pvt.c
index 61363ba..7689e9b 100644
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -132,6 +132,10 @@
 		goto out;
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	/*
 	 * Read frequencies. If failure, load default values.
 	 */
@@ -398,11 +402,9 @@
  */
 static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd)
 {
-	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) {
-		return -EFAULT;
-	}
+	uint32_t i;
 
-	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, 1497600000)) {
+	if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) {
 		return -EFAULT;
 	}
 
@@ -422,6 +424,85 @@
 		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;
+	}
+
+	/*
+	 * 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", 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 MHz ");
+		} else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) {
+			nss_info_always("748 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.689 GHz ");
+		} else {
+			nss_info_always("Error\nNo Table/Invalid Frequency Found");
+			return -EFAULT;
+		}
+	}
+	nss_info_always("\n");
+
+	/*
+	 * Set values only once for core0. Grab the proper clock.
+	 */
+	if (nss_ctx->id) {
+		nss_core1_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK);
+	} else {
+		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;
 }
 
@@ -517,6 +598,12 @@
 		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 (err) {
 		return err;
 	}
@@ -542,4 +629,3 @@
 	.clear_interrupt_cause = __nss_hal_clear_interrupt_cause,
 	.read_interrupt_cause = __nss_hal_read_interrupt_cause,
 };
-
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index d0959e9..28372f2 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -326,6 +326,8 @@
 	}
 	spin_lock_bh(&(nss_top->lock));
 
+	nss_top->num_pri = npd->num_pri;
+
 	/*
 	 * Features that will always be enabled on both cores
 	 */
diff --git a/nss_init.c b/nss_init.c
index 826ca80..433d508 100644
--- a/nss_init.c
+++ b/nss_init.c
@@ -73,6 +73,7 @@
  * Handler to send NSS messages
  */
 struct clk *nss_core0_clk;
+struct clk *nss_core1_clk;
 
 /*
  * Handle fabric requests - only on new kernel
@@ -197,10 +198,14 @@
 		nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
 	}
 	clk_set_rate(nss_core0_clk, my_work->frequency);
+
 	nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1);
 	if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
 		nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1);
 	}
+#if defined(NSS_HAL_IPQ807x_SUPPORT)
+	clk_set_rate(nss_core1_clk, my_work->frequency);
+#endif
 
 /*
  * If we are running NSS_PM_SUPPORT, we are on banana
diff --git a/nss_ipv4.c b/nss_ipv4.c
index 7930be3..b2b9e8a 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -55,6 +55,37 @@
 EXPORT_SYMBOL(nss_ipv4_max_conn_count);
 
 /*
+ * nss_ipv4_conn_inquiry()
+ *	Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv4_conn_inquiry(struct nss_ipv4_5tuple *ipv4_5t_p,
+				nss_ipv4_msg_callback_t cb)
+{
+	nss_tx_status_t nss_tx_status;
+	struct nss_ipv4_msg nim;
+	struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
+
+	/*
+	 * Initialize inquiry message structure.
+	 * This is async message and the result will be returned
+	 * to the caller by the msg_callback passed in.
+	 */
+	memset(&nim, 0, sizeof(nim));
+	nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE,
+			NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
+			sizeof(struct nss_ipv4_inquiry_msg),
+			cb, NULL);
+	nim.msg.inquiry.rr.tuple = *ipv4_5t_p;
+	nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
+	if (nss_tx_status != NSS_TX_SUCCESS) {
+		nss_warning("%p: Send inquiry message failed\n", ipv4_5t_p);
+	}
+
+	return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv4_conn_inquiry);
+
+/*
  * nss_ipv4_driver_conn_sync_update()
  *	Update driver specific information from the messsage.
  */
diff --git a/nss_ipv6.c b/nss_ipv6.c
index 430d260..c5a6590 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -54,6 +54,37 @@
 EXPORT_SYMBOL(nss_ipv6_max_conn_count);
 
 /*
+ * nss_ipv6_conn_inquiry()
+ *	Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p,
+				nss_ipv6_msg_callback_t cb)
+{
+	nss_tx_status_t nss_tx_status;
+	struct nss_ipv6_msg nim;
+	struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
+
+	/*
+	 * Initialize inquiry message structure.
+	 * This is async message and the result will be returned
+	 * to the caller by the msg_callback passed in.
+	 */
+	memset(&nim, 0, sizeof(nim));
+	nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE,
+			NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
+			sizeof(struct nss_ipv6_inquiry_msg),
+			cb, NULL);
+	nim.msg.inquiry.rr.tuple = *ipv6_5t_p;
+	nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+	if (nss_tx_status != NSS_TX_SUCCESS) {
+		nss_warning("%p: Send inquiry message failed\n", ipv6_5t_p);
+	}
+
+	return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv6_conn_inquiry);
+
+/*
  * nss_ipv6_driver_conn_sync_update()
  *	Update driver specific information from the messsage.
  */
diff --git a/nss_map_t.c b/nss_map_t.c
index e88b369..b40f227 100644
--- a/nss_map_t.c
+++ b/nss_map_t.c
@@ -45,7 +45,7 @@
 		return false;
 	}
 
-	if (nss_dynamic_interface_get_type(if_num)
+	if (nss_dynamic_interface_get_type(nss_map_t_get_context(), if_num)
 	    != NSS_DYNAMIC_INTERFACE_TYPE_MAP_T) {
 		return false;
 	}
diff --git a/nss_n2h.c b/nss_n2h.c
index 7981a01..f7a2717 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -777,6 +777,58 @@
 }
 
 /*
+ * nss_n2h_update_queue_config()
+ *	Updates pnode queue configuration and limits
+ */
+nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int num_pri, int *qlimits)
+{
+	struct nss_n2h_msg nnm;
+	struct nss_n2h_pnode_queue_config *cfg;
+	nss_tx_status_t status;
+	struct nss_top_instance *nss_top = &nss_top_main;
+	struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+	int i;
+
+	if (!mq_en) {
+		return NSS_TX_SUCCESS;
+	}
+
+	if (num_pri <= 0) {
+		nss_warning("%p: nss_tx error in pnode queue config param", nss_ctx);
+		return NSS_TX_FAILURE_BAD_PARAM;
+	}
+
+	if (max_pri < num_pri) {
+		nss_warning("%p: nss_tx error in pnode queue config param, maximum supported priority is %d", nss_ctx, max_pri);
+		return NSS_TX_FAILURE_BAD_PARAM;
+	}
+
+	cfg = &nnm.msg.pn_q_cfg;
+	cfg->num_pri = num_pri;
+	for (i = 0; i < num_pri; i++) {
+		cfg->qlimits[i] = qlimits[i];
+	}
+	cfg->mq_en = true;
+
+	/*
+	 * Create message for FW
+	 */
+	nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
+			 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
+			 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
+
+	status = nss_n2h_tx_msg(nss_ctx, &nnm);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
+		return status;
+	}
+
+	return NSS_TX_SUCCESS;
+
+}
+EXPORT_SYMBOL(nss_n2h_update_queue_config);
+
+/*
  * nss_n2h_rps_cfg()
  *	Send Message to NSS to enable RPS.
  */
@@ -1235,7 +1287,6 @@
 	{ }
 };
 
-
 static struct ctl_table nss_n2h_root_dir[] = {
 	{
 		.procname		= "nss",
@@ -1334,7 +1385,6 @@
 		return NSS_TX_FAILURE;
 	}
 
-
 	nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
 	if (unlikely(!nbuf)) {
 		NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
diff --git a/nss_phys_if.c b/nss_phys_if.c
index 2f1cd2f..9752c36 100644
--- a/nss_phys_if.c
+++ b/nss_phys_if.c
@@ -20,6 +20,7 @@
  */
 
 #include "nss_tx_rx_common.h"
+#include "nss_tstamp.h"
 
 #define NSS_PHYS_IF_TX_TIMEOUT 3000 /* 3 Seconds */
 
@@ -169,9 +170,12 @@
 		return NSS_TX_FAILURE_NOT_READY;
 	}
 
-	/* Check if we need the packet to be timestamped by GMAC Hardware at Tx */
+	/*
+	 * If we need the packet to be timestamped by GMAC Hardware at Tx
+	 * send the packet to tstamp NSS module
+	 */
 	if (unlikely(skb_shinfo(os_buf)->tx_flags & SKBTX_HW_TSTAMP)) {
-		flags |= H2N_BIT_FLAG_TX_TS_REQUIRED;
+		return nss_tstamp_tx_buf(nss_ctx, os_buf, if_num);
 	}
 
 	status = nss_core_send_buffer(nss_ctx, if_num, os_buf, NSS_IF_DATA_QUEUE_0, H2N_BUFFER_PACKET, flags);
@@ -190,6 +194,7 @@
 	nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
 
 	NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
+
 	return NSS_TX_SUCCESS;
 }
 
diff --git a/nss_portid.c b/nss_portid.c
index cf317e6..bc9b30a 100644
--- a/nss_portid.c
+++ b/nss_portid.c
@@ -174,7 +174,7 @@
 		return false;
 	}
 
-	if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_PORTID) {
+	if (nss_dynamic_interface_get_type(nss_portid_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_PORTID) {
 		return false;
 	}
 
diff --git a/nss_ppe.c b/nss_ppe.c
index 1ccd7d6..c66327e 100644
--- a/nss_ppe.c
+++ b/nss_ppe.c
@@ -158,13 +158,177 @@
 }
 
 /*
+ * nss_ppe_callback()
+ *	Callback to handle the completion of NSS->HLOS messages.
+ */
+static void nss_ppe_callback(void *app_data, struct nss_ppe_msg *npm)
+{
+	nss_ppe_msg_callback_t callback = (nss_ppe_msg_callback_t)ppe_pvt.cb;
+	void *data = ppe_pvt.app_data;
+
+	ppe_pvt.response = NSS_TX_SUCCESS;
+	ppe_pvt.cb = NULL;
+	ppe_pvt.app_data = NULL;
+
+	if (npm->cm.response != NSS_CMN_RESPONSE_ACK) {
+		nss_warning("ppe error response %d\n", npm->cm.response);
+		ppe_pvt.response = npm->cm.response;
+	}
+
+	if (callback) {
+		callback(data, npm);
+	}
+	complete(&ppe_pvt.complete);
+}
+
+/*
+ * nss_ppe_tx_msg()
+ *	Transmit a ppe message to NSSFW
+ */
+nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg)
+{
+	struct nss_ppe_msg *nm;
+	struct nss_cmn_msg *ncm = &msg->cm;
+	struct sk_buff *nbuf;
+	int32_t status;
+
+	NSS_VERIFY_CTX_MAGIC(nss_ctx);
+	if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
+		nss_warning("%p: ppe msg dropped as core not ready\n", nss_ctx);
+		return NSS_TX_FAILURE_NOT_READY;
+	}
+
+	/*
+	 * Sanity check the message
+	 */
+	if (ncm->type >= NSS_PPE_MSG_MAX) {
+		nss_warning("%p: message type out of range: %d\n", nss_ctx, ncm->type);
+		return NSS_TX_FAILURE;
+	}
+
+	if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
+		nss_warning("%p: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
+		return NSS_TX_FAILURE;
+	}
+
+	nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
+	if (unlikely(!nbuf)) {
+		NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
+		nss_warning("%p: msg dropped as command allocation failed\n", nss_ctx);
+		return NSS_TX_FAILURE;
+	}
+
+	/*
+	 * Copy the message to our skb
+	 */
+	nm = (struct nss_ppe_msg *)skb_put(nbuf, sizeof(struct nss_ppe_msg));
+	memcpy(nm, msg, sizeof(struct nss_ppe_msg));
+
+	status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
+	if (status != NSS_CORE_STATUS_SUCCESS) {
+		dev_kfree_skb_any(nbuf);
+		nss_warning("%p: Unable to enqueue 'ppe message'\n", nss_ctx);
+		return NSS_TX_FAILURE;
+	}
+
+	nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
+
+	NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
+	return NSS_TX_SUCCESS;
+}
+EXPORT_SYMBOL(nss_ppe_tx_msg);
+
+/*
+ * nss_ppe_tx_msg_sync()
+ *	Transmit a ppe message to NSS firmware synchronously.
+ */
+nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *npm)
+{
+	nss_tx_status_t status;
+	int ret = 0;
+
+	down(&ppe_pvt.sem);
+	ppe_pvt.cb = (void *)npm->cm.cb;
+	ppe_pvt.app_data = (void *)npm->cm.app_data;
+
+	npm->cm.cb = (nss_ptr_t)nss_ppe_callback;
+	npm->cm.app_data = (nss_ptr_t)NULL;
+
+	status = nss_ppe_tx_msg(nss_ctx, npm);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: ppe_tx_msg failed\n", nss_ctx);
+		up(&ppe_pvt.sem);
+		return status;
+	}
+
+	ret = wait_for_completion_timeout(&ppe_pvt.complete, msecs_to_jiffies(NSS_PPE_TX_TIMEOUT));
+	if (!ret) {
+		nss_warning("%p: ppe msg tx failed due to timeout\n", nss_ctx);
+		ppe_pvt.response = NSS_TX_FAILURE;
+	}
+
+	status = ppe_pvt.response;
+	up(&ppe_pvt.sem);
+	return status;
+}
+EXPORT_SYMBOL(nss_ppe_tx_msg_sync);
+
+/*
+ * nss_ppe_get_context()
+ *	Get NSS context instance for ppe
+ */
+struct nss_ctx_instance *nss_ppe_get_context(void)
+{
+	return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id];
+}
+EXPORT_SYMBOL(nss_ppe_get_context);
+
+/*
+ * nss_ppe_msg_init()
+ *	Initialize nss_ppe_msg.
+ */
+void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
+{
+	nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data);
+}
+EXPORT_SYMBOL(nss_ppe_msg_init);
+
+/*
+ * nss_ppe_tx_l2_exception_msg
+ *	API to send vsi assign message to NSS FW
+ */
+nss_tx_status_t nss_ppe_tx_l2_exception_msg(uint32_t if_num, bool exception_enable)
+{
+	struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
+	struct nss_ppe_msg npm;
+
+	if (!nss_ctx) {
+		nss_warning("Can't get nss context\n");
+		return NSS_TX_FAILURE;
+	}
+
+	if (!nss_ppe_verify_ifnum(if_num)) {
+		nss_warning("%p: invalid interface %d\n", nss_ctx, if_num);
+		return NSS_TX_FAILURE;
+	}
+
+	nss_ppe_msg_init(&npm, if_num, NSS_PPE_MSG_L2_EXCEPTION,
+			sizeof(struct nss_ppe_l2_exception_msg), NULL, NULL);
+
+	npm.msg.l2_exception.l2_exception_enable = exception_enable;
+
+	return nss_ppe_tx_msg_sync(nss_ctx, &npm);
+}
+EXPORT_SYMBOL(nss_ppe_tx_l2_exception_msg);
+
+/*
  * nss_ppe_stats_conn_get()
  *	Get ppe connection stats.
  */
 void nss_ppe_stats_conn_get(uint32_t *stats)
 {
 	if (!stats) {
-		nss_warning("No memory to copy ppe connection stats");
+		nss_warning("No memory to copy ppe connection stats\n");
 		return;
 	}
 
@@ -348,25 +512,28 @@
 
 /*
  * nss_ppe_handler()
- *	Handle NSS -> HLOS messages for ppe tunnel
+ *	Handle NSS -> HLOS messages for ppe
  */
 static void nss_ppe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
 {
 	struct nss_ppe_msg *msg = (struct nss_ppe_msg *)ncm;
+	void *ctx;
 
-	nss_trace("nss_ctx: %p ppe msg: %p", nss_ctx, msg);
+	nss_ppe_msg_callback_t cb;
+
+	nss_trace("nss_ctx: %p ppe msg: %p\n", nss_ctx, msg);
 	BUG_ON(!nss_ppe_verify_ifnum(ncm->interface));
 
 	/*
 	 * Is this a valid request/response packet?
 	 */
 	if (ncm->type >= NSS_PPE_MSG_MAX) {
-		nss_warning("%p: received invalid message %d for PPE interface", nss_ctx, ncm->type);
+		nss_warning("%p: received invalid message %d for PPE interface\n", nss_ctx, ncm->type);
 		return;
 	}
 
 	if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
-		nss_warning("%p: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
+		nss_warning("%p: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
 		return;
 	}
 
@@ -376,19 +543,29 @@
 		 * session debug stats embeded in session stats msg
 		 */
 		nss_ppe_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface);
-		break;
+		return;
 	}
-}
 
-/*
- * nss_ppe_get_context()
- * 	get NSS context instance for ppe
- */
-struct nss_ctx_instance *nss_ppe_get_context(void)
-{
-	return &nss_top_main.nss[nss_top_main.ppe_handler_id];
+	/*
+	 * Log failures
+	 */
+	nss_core_log_msg_failures(nss_ctx, ncm);
+
+	/*
+	 * Do we have a call back
+	 */
+	if (!ncm->cb) {
+		return;
+	}
+
+	/*
+	 * callback
+	 */
+	cb = (nss_ppe_msg_callback_t)ncm->cb;
+	ctx = (void *)ncm->app_data;
+
+	cb(ctx, msg);
 }
-EXPORT_SYMBOL(nss_ppe_get_context);
 
 /*
  * nss_ppe_register_handler()
@@ -456,4 +633,7 @@
 	nss_ppe_debug_stats.if_num = 0;
 	nss_ppe_debug_stats.if_index = 0;
 	spin_unlock_bh(&nss_ppe_stats_lock);
+
+	sema_init(&ppe_pvt.sem, 1);
+	init_completion(&ppe_pvt.complete);
 }
diff --git a/nss_ppe.h b/nss_ppe.h
index d0889a5..7139819 100644
--- a/nss_ppe.h
+++ b/nss_ppe.h
@@ -68,6 +68,8 @@
 #define PPE_DROP_CODE_IDX(code, src_port) (PPE_CPU_CODE_MAX_NUM + (8 * (code)) + (src_port))
 #define PPE_DROP_CODE_OFFSET(code, src_port) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((PPE_DROP_CODE_IDX(code, src_port)) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE))
 
+#define NSS_PPE_TX_TIMEOUT 1000 /* 1 Second */
+
 /*
  * Data structures to store ppe nss debug stats
  */
@@ -79,6 +81,11 @@
  */
 static struct nss_ppe_pvt {
 	void * __iomem ppe_base;
+	struct semaphore sem;
+	struct completion complete;
+	int response;
+	void *cb;
+	void *app_data;
 } ppe_pvt;
 
 /*
diff --git a/nss_stats.c b/nss_stats.c
index 6a22315..d8adebc 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -281,7 +281,8 @@
 	"tx_cmpl_buf_full_err",
 	"pkt_len_la64k_err",
 	"pkt_len_le33_err",
-	"data_len_err"
+	"data_len_err",
+	"alloc_fail_cnt"
 };
 
 /*
@@ -3707,7 +3708,7 @@
 			continue;
 		}
 
-		if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
+		if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
 			continue;
 		}
 
@@ -3904,6 +3905,7 @@
 static ssize_t nss_stats_wifi_if_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
 {
 	struct nss_stats_data *data = fp->private_data;
+	struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
 	int32_t if_num = NSS_DYNAMIC_IF_START;
 	int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
 	size_t bytes = 0;
@@ -3920,7 +3922,7 @@
 	}
 
 	for (; if_num < max_if_num; if_num++) {
-		if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
+		if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
 			continue;
 
 		bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
@@ -3985,6 +3987,7 @@
 						size_t sz, loff_t *ppos)
 {
 	struct nss_stats_data *data = fp->private_data;
+	struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
 	int32_t if_num = NSS_DYNAMIC_IF_START;
 	int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
 	size_t bytes = 0;
@@ -4001,7 +4004,7 @@
 	}
 
 	for (; if_num < max_if_num; if_num++) {
-		if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
+		if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
 			continue;
 
 		bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
@@ -4066,6 +4069,7 @@
 						size_t sz, loff_t *ppos)
 {
 	struct nss_stats_data *data = fp->private_data;
+	struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
 	int32_t if_num = NSS_DYNAMIC_IF_START;
 	int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
 	size_t bytes = 0;
@@ -4082,7 +4086,7 @@
 	}
 
 	for (; if_num < max_if_num; if_num++) {
-		if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
+		if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
 			continue;
 
 		bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
diff --git a/nss_tstamp.c b/nss_tstamp.c
index a59e286..ba04b35 100644
--- a/nss_tstamp.c
+++ b/nss_tstamp.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2015, 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 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.
@@ -19,24 +19,26 @@
  *	NSS Tstamp APIs
  */
 
-#include "nss_tx_rx_common.h"
+#include <linux/ip.h>
+#include <linux/ipv6.h>
 #include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <net/route.h>
+#include <net/ip6_route.h>
+#include "nss_tx_rx_common.h"
+#include "nss_tstamp.h"
+
+#define NSS_TSTAMP_HEADER_SIZE max(sizeof(struct nss_tstamp_h2n_pre_hdr), sizeof(struct nss_tstamp_n2h_pre_hdr))
 
 static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev);
 
+/*
+ * dummy netdevice ops
+ */
 static const struct net_device_ops nss_tstamp_ndev_ops = {
 	.ndo_get_stats = nss_tstamp_ndev_stats,
 };
 
-struct nss_tstamp_data {
-	uint32_t ts_ifnum;	/* time stamp interface number */
-	uint32_t ts_data_lo;	/* time stamp lower order bits */
-	uint32_t ts_data_hi;	/* time stamp higher order bits */
-
-	uint8_t ts_tx;		/* time stamp direction */
-	uint8_t ts_hdr_sz;	/* padding bytes */
-};
-
 /*
  * nss_tstamp_ndev_setup()
  *	Dummy setup for net_device handler
@@ -53,13 +55,13 @@
 static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev)
 {
 	return &ndev->stats;
-};
+}
 
 /*
  * nss_tstamp_copy_data()
  *	Copy timestamps from received nss frame into skb
  */
-static void nss_tstamp_copy_data(struct nss_tstamp_data *ntm, struct sk_buff *skb)
+static void nss_tstamp_copy_data(struct nss_tstamp_n2h_pre_hdr *ntm, struct sk_buff *skb)
 {
 	struct skb_shared_hwtstamps *tstamp;
 
@@ -71,39 +73,91 @@
 }
 
 /*
+ * nss_tstamp_get_dev()
+ *	Get the net_device associated with the packet.
+ */
+static struct net_device *nss_tstamp_get_dev(struct sk_buff *skb)
+{
+	struct dst_entry *dst;
+	struct net_device *dev;
+	struct rtable *rt;
+	struct flowi6 fl6;
+	uint32_t ip_addr;
+
+	/*
+	 * It seems like the data came over IPsec, hence indicate
+	 * it to the Linux over this interface
+	 */
+	skb_reset_network_header(skb);
+	skb_reset_mac_header(skb);
+
+	skb->pkt_type = PACKET_HOST;
+
+	switch (ip_hdr(skb)->version) {
+	case IPVERSION:
+		ip_addr = ip_hdr(skb)->saddr;
+
+		rt = ip_route_output(&init_net, ip_addr, 0, 0, 0);
+		if (IS_ERR(rt)) {
+			return NULL;
+		}
+
+		dst = (struct dst_entry *)rt;
+		skb->protocol = cpu_to_be16(ETH_P_IP);
+		break;
+
+	case 6:
+		memset(&fl6, 0, sizeof(fl6));
+		memcpy(&fl6.daddr, &ipv6_hdr(skb)->saddr, sizeof(fl6.daddr));
+
+		dst = ip6_route_output(&init_net, NULL, &fl6);
+		if (IS_ERR(dst)) {
+			return NULL;
+		}
+
+		skb->protocol = cpu_to_be16(ETH_P_IPV6);
+		break;
+
+	default:
+		nss_warning("%p:could not get dev for the skb\n", skb);
+		return NULL;
+	}
+
+	dev = dst->dev;
+	dev_hold(dev);
+
+	dst_release(dst);
+	return dev;
+}
+
+/*
  * nss_tstamp_buf_receive()
  * 	Receive nss exception packets.
  */
 static void nss_tstamp_buf_receive(struct net_device *ndev, struct sk_buff *skb, struct napi_struct *napi)
 {
-	struct nss_tstamp_data *ntm = (struct nss_tstamp_data *)skb->data;
+	struct nss_tstamp_n2h_pre_hdr *n2h_hdr = (struct nss_tstamp_n2h_pre_hdr *)skb->data;
 	struct nss_ctx_instance *nss_ctx;
 	struct net_device *dev;
 	uint32_t tstamp_sz;
 
-	BUG_ON(!ntm);
-	tstamp_sz = ntm->ts_hdr_sz;
+	BUG_ON(!n2h_hdr);
+
+	tstamp_sz = n2h_hdr->ts_hdr_sz;
+	if (tstamp_sz > (NSS_TSTAMP_HEADER_SIZE + sizeof(uint32_t))) {
+		goto free;
+	}
 
 	nss_ctx = &nss_top_main.nss[nss_top_main.tstamp_handler_id];
 	BUG_ON(!nss_ctx);
 
-	skb_pull(skb, tstamp_sz);
-
-	dev = nss_cmn_get_interface_dev(nss_ctx, ntm->ts_ifnum);
-	if (!dev) {
-		nss_warning("Tstamp: Invalid net device\n");
-		dev_kfree_skb_any(skb);
-		return;
-	}
-
-	skb->dev = dev;
+	skb_pull_inline(skb, tstamp_sz);
 
 	/*
 	 * copy the time stamp and convert into ktime_t
 	 */
-	nss_tstamp_copy_data(ntm, skb);
-
-	if (unlikely(ntm->ts_tx)) {
+	nss_tstamp_copy_data(n2h_hdr, skb);
+	if (unlikely(n2h_hdr->ts_tx)) {
 		/*
 		 * We are in TX Path
 		 */
@@ -111,26 +165,34 @@
 
 		ndev->stats.tx_packets++;
 		ndev->stats.tx_bytes += skb->len;
-
-		dev_kfree_skb_any(skb);
-		return;
+		goto free;
 	}
 
 	/*
-	 * We are in RX Path
+	 * We are in RX path.
 	 */
+	dev = nss_cmn_get_interface_dev(nss_ctx, n2h_hdr->ts_ifnum);
+	if (!dev) {
+		ndev->stats.rx_dropped++;
+		goto free;
+	}
+
+	/*
+	 * Hold the dev until we finish
+	 */
+	dev_hold(dev);
+
 	switch(dev->type) {
 	case NSS_IPSEC_ARPHRD_IPSEC:
 		/*
-		 * It seems like the data came over IPsec, hence indicate
-		 * it to the Linux over this interface
+		 * Release the prev dev reference
 		 */
-		skb_reset_network_header(skb);
-		skb_reset_mac_header(skb);
+		dev_put(dev);
 
-		skb->pkt_type = PACKET_HOST;
-		skb->protocol = cpu_to_be16(ETH_P_IP);
-		skb->skb_iif = dev->ifindex;
+		/*
+		 * find the actual IPsec tunnel device
+		 */
+		dev = nss_tstamp_get_dev(skb);
 		break;
 
 	default:
@@ -141,14 +203,27 @@
 		break;
 	}
 
-	netif_receive_skb(skb);
+	skb->skb_iif = dev->ifindex;
+	skb->dev = dev;
 
 	ndev->stats.rx_packets++;
 	ndev->stats.rx_bytes += skb->len;
+
+	netif_receive_skb(skb);
+
+	/*
+	 * release the device as we are done
+	 */
+	dev_put(dev);
+	return;
+free:
+	dev_kfree_skb_any(skb);
+	return;
 }
 
 /*
  * nss_tstamp_register_netdev()
+ *	register dummy netdevice for tstamp interface
  */
 struct net_device *nss_tstamp_register_netdev(void)
 {
@@ -192,4 +267,66 @@
 	nss_ctx->subsys_dp_register[NSS_TSTAMP_INTERFACE].features = features;
 }
 
+/*
+ * nss_tstamp_tx_buf()
+ *	Send data packet for tstamp processing
+ */
+nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num)
+{
+	struct nss_tstamp_h2n_pre_hdr *h2n_hdr;
+	nss_tx_status_t status;
+	bool expand_head;
+	char *align_data;
+	uint32_t hdr_sz;
+
+	nss_trace("%p: Tstamp If Tx packet, id:%d, data=%p", nss_ctx, NSS_TSTAMP_INTERFACE, skb->data);
+
+	if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
+		nss_trace("%p: tstamp tx_packet dropped as core is not ready", nss_ctx);
+		return NSS_TX_FAILURE_NOT_READY;
+	}
+
+	/*
+	 * header size + alignment size
+	 */
+	hdr_sz = NSS_TSTAMP_HEADER_SIZE + sizeof(uint32_t);
+	expand_head = (hdr_sz > skb_headroom(skb));
+
+	/*
+	 * Expand the head for h2n_hdr
+	 */
+	if (expand_head && pskb_expand_head(skb, hdr_sz, 0, GFP_KERNEL)) {
+		nss_trace("%p: expand head room failed", nss_ctx);
+		return NSS_TX_FAILURE;
+	}
+
+	align_data = PTR_ALIGN((skb->data - hdr_sz), sizeof(uint32_t));
+	hdr_sz = (nss_ptr_t)skb->data - (nss_ptr_t)align_data;
+
+	h2n_hdr = (struct nss_tstamp_h2n_pre_hdr *)skb_push(skb, hdr_sz);
+	h2n_hdr->ts_ifnum = if_num;
+	h2n_hdr->ts_tx_hdr_sz = hdr_sz;
+
+	status = nss_core_send_buffer(nss_ctx, NSS_TSTAMP_INTERFACE, skb, NSS_IF_DATA_QUEUE_0,
+					H2N_BUFFER_PACKET, H2N_BIT_FLAG_VIRTUAL_BUFFER);
+
+	switch (status) {
+	case NSS_CORE_STATUS_SUCCESS:
+		/*
+		 * Kick the NSS awake so it can process our new entry.
+		 */
+		nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
+		NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
+		break;
+
+	case NSS_CORE_STATUS_FAILURE_QUEUE:
+		return NSS_TX_FAILURE_QUEUE;
+
+	default:
+		return NSS_TX_FAILURE;
+	}
+
+	return NSS_TX_SUCCESS;
+}
+EXPORT_SYMBOL(nss_tstamp_tx_buf);
 
diff --git a/nss_vlan.c b/nss_vlan.c
index d562127..1fd5d3f 100644
--- a/nss_vlan.c
+++ b/nss_vlan.c
@@ -30,6 +30,15 @@
 } vlan_pvt;
 
 /*
+ * nss_vlan_get_context()
+ */
+struct nss_ctx_instance *nss_vlan_get_context(void)
+{
+	return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.vlan_handler_id];
+}
+EXPORT_SYMBOL(nss_vlan_get_context);
+
+/*
  * nss_vlan_verify_if_num()
  *	Verify if_num passed to us.
  */
@@ -39,7 +48,7 @@
 		return false;
 	}
 
-	if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VLAN) {
+	if (nss_dynamic_interface_get_type(nss_vlan_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VLAN) {
 		return false;
 	}
 
@@ -220,15 +229,6 @@
 EXPORT_SYMBOL(nss_vlan_tx_msg_sync);
 
 /*
- * nss_vlan_get_context()
- */
-struct nss_ctx_instance *nss_vlan_get_context(void)
-{
-	return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.vlan_handler_id];
-}
-EXPORT_SYMBOL(nss_vlan_get_context);
-
-/*
  * nss_vlan_msg_init()
  *	Initialize nss_vlan_msg.
  */