Merge "[qca-nss-drv] WIFILI Log"
diff --git a/Makefile b/Makefile
index cc72197..d998548 100644
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,7 @@
 			nss_core.o \
 			nss_coredump.o \
 			nss_dynamic_interface.o \
+			nss_dynamic_interface_log.o \
 			nss_edma.o \
 			nss_edma_stats.o \
 			nss_eth_rx.o \
@@ -39,6 +40,7 @@
 			nss_gre_redir_lag_us_stats.o \
 			nss_gre_redir_stats.o \
 			nss_gre_tunnel.o \
+			nss_gre_tunnel_log.o \
 			nss_gre_tunnel_stats.o \
 			nss_if.o \
 			nss_init.o \
@@ -103,12 +105,14 @@
 			nss_trustsec_tx_stats.o \
 			nss_tunipip6.o \
 			nss_tunipip6_log.o \
+			nss_tx_msg_sync.o \
 			nss_virt_if.o \
 			nss_virt_if_stats.o \
 			nss_vlan.o \
 			nss_vlan_log.o \
 			nss_tstamp.o \
 			nss_wifi.o \
+			nss_wifi_log.o \
 			nss_wifi_stats.o \
 			nss_wifi_vdev.o \
 			nss_wifi_if.o \
@@ -128,7 +132,8 @@
 			nss_dtls.o \
 			nss_dtls_log.o \
 			nss_dtls_stats.o \
-			nss_crypto.o
+			nss_crypto.o \
+			nss_crypto_log.o
 ccflags-y += -I$(obj)/nss_hal/ipq806x -DNSS_HAL_IPQ806X_SUPPORT
 endif
 
diff --git a/Makefile.fsm b/Makefile.fsm
index 5acbb96..7f23771 100644
--- a/Makefile.fsm
+++ b/Makefile.fsm
@@ -16,10 +16,12 @@
 			nss_core.o \
 			nss_coredump.o \
 			nss_crypto.o \
+			nss_crypto_log.o \
 			nss_dtls.o \
 			nss_dtls_log.o \
 			nss_dtls_stats.o \
 			nss_dynamic_interface.o \
+			nss_dynamic_interface_log.o \
 			nss_edma.o \
 			nss_edma_stats.o \
 			nss_eth_rx.o \
@@ -31,6 +33,7 @@
 			nss_gre_redir_log.o \
 			nss_gre_redir_stats.o \
 			nss_gre_tunnel.o \
+			nss_gre_tunnel_log.o \
 			nss_gre_tunnel_stats.o \
 			nss_if.o \
 			nss_init.o \
@@ -95,6 +98,7 @@
 			nss_vlan.o \
 			nss_vlan_log.o \
 			nss_wifi.o \
+			nss_wifi_log.o \
 			nss_wifi_stats.o \
 			nss_wifi_if.o \
 			nss_wifi_if_stats.o \
diff --git a/exports/nss_cmn.h b/exports/nss_cmn.h
index 9cf058a..33bb6b5 100644
--- a/exports/nss_cmn.h
+++ b/exports/nss_cmn.h
@@ -63,6 +63,8 @@
 /**
  * nss_tx_status_t
  *	Tx command failure results.
+ *
+ * Types starting with NSS_TX_FAILURE_SYNC_ are only used by synchronous messages.
  */
 typedef enum {
 	NSS_TX_SUCCESS = 0,
@@ -74,6 +76,9 @@
 	NSS_TX_FAILURE_NOT_SUPPORTED,
 	NSS_TX_FAILURE_BAD_PARAM,
 	NSS_TX_FAILURE_NOT_ENABLED,
+	NSS_TX_FAILURE_SYNC_BAD_PARAM,
+	NSS_TX_FAILURE_SYNC_TIMEOUT,
+	NSS_TX_FAILURE_SYNC_FW_ERR,
 } nss_tx_status_t;
 
 /**
@@ -194,7 +199,7 @@
 
 /**
  * nss_cmn_msg_init
- *	Initializes the common area of a host-to-NSS message.
+ *	Initializes the common area of an asynchronous host-to-NSS message.
  *
  * @datatypes
  * nss_cmn_msg
@@ -209,10 +214,27 @@
  * @return
  * None.
  */
-extern void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type,  uint32_t len,
+extern void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len,
 	void *cb, void *app_data);
 
 /**
+ * nss_cmn_msg_sync_init
+ *	Initializes the common message of a synchronous host-to-NSS message.
+ *
+ * @datatypes
+ * nss_cmn_msg
+ *
+ * @param[in,out] ncm     Pointer to the common message.
+ * @param[in]     if_num  NSS interface number.
+ * @param[in]     type    Type of message.
+ * @param[in]     len     Size of the payload.
+ *
+ * @return
+ * None.
+ */
+extern void nss_cmn_msg_sync_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type,  uint32_t len);
+
+/**
  * nss_cmn_get_interface_number
  *	Gets the interface number.
  *
@@ -249,8 +271,8 @@
  * @datatypes
  * net_device
  *
- * @param[in] dev  Pointer to the OS network device pointer.
- * @param[in] type Type of this interface.
+ * @param[in] dev   Pointer to the OS network device pointer.
+ * @param[in] type  Type of this interface.
  *
  * @return
  * Interface number, or -1 on failure.
@@ -277,7 +299,7 @@
  * nss_ctx_instance
  *
  * @param[in] nss_ctx  Pointer to the NSS context.
- * @param[in] if_num     NSS interface number.
+ * @param[in] if_num   NSS interface number.
  *
  * @return
  * Interface device pointer.
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index dceaa3b..e172df6 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -96,6 +96,22 @@
 };
 
 /**
+ * nss_dynamic_interface_error_types
+ *	Error types for dynamic interface requests.
+ */
+enum nss_dynamic_interface_error_types {
+	NSS_DYNAMIC_INTERFACE_ERR_EUNKNOWN = 1,
+	NSS_DYNAMIC_INTERFACE_ERR_EUNAVAIL,
+	NSS_DYNAMIC_INTERFACE_ERR_INVALID_TYPE,
+	NSS_DYNAMIC_INTERFACE_ERR_INVALID_INTERFACE_NUM,
+	NSS_DYNAMIC_INTERFACE_ERR_ALLOC_FUNC_UNAVAILABLE,
+	NSS_DYNAMIC_INTERFACE_ERR_DEALLOC_FUNC_UNAVAILABLE,
+	NSS_DYNAMIC_INTERFACE_ERR_EALLOC,
+	NSS_DYNAMIC_INTERFACE_ERR_IFNUM_TYPE_MISMATCH,
+	NSS_DYNAMIC_INTERFACE_ERR_MAX,
+};
+
+/**
  * nss_dynamic_interface_alloc_node_msg
  *	Message information for a dynamic interface allocation node.
  */
diff --git a/exports/nss_wifi.h b/exports/nss_wifi.h
index 6669b1e..4be0258 100644
--- a/exports/nss_wifi.h
+++ b/exports/nss_wifi.h
@@ -124,6 +124,7 @@
 	NSS_WIFI_EMSG_PEERID_INVALID,
 	NSS_WIFI_EMSG_PEER_INVALID,
 	NSS_WIFI_EMSG_UNKNOWN_CMD,
+	NSS_WIFI_EMSG_MAX,
 };
 
 /**
diff --git a/exports/nss_wifi_vdev.h b/exports/nss_wifi_vdev.h
index d0edf09..d7d5344 100644
--- a/exports/nss_wifi_vdev.h
+++ b/exports/nss_wifi_vdev.h
@@ -167,6 +167,7 @@
 	NSS_WIFI_VDEV_CFG_WDS_CMD,		/**< Configuration to set WDS on VAP. */
 	NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD,        /**< Configuration to enable/disable client isolation. */
 	NSS_WIFI_VDEV_SECURITY_TYPE_CMD,	/**< Configuration to set security type per VAP. */
+	NSS_WIFI_VDEV_CFG_AST_OVERRIDE_CMD,	/**< Configuration to set AST (Address Search Table) override on VAP. */
 	NSS_WIFI_VDEV_MAX_CMD
 };
 
diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h
index e2fa4b9..757783e 100644
--- a/exports/nss_wifili_if.h
+++ b/exports/nss_wifili_if.h
@@ -366,6 +366,10 @@
 			/**< Count of the software descriptors for second radio. */
 	uint32_t num_tx_desc_ext_2;
 			/**< Count of software extended descriptors for second radio. */
+	uint32_t num_tx_desc_3;
+			/**< Count of the software descriptors for third radio. */
+	uint32_t num_tx_desc_ext_3;
+			/**< Count of software extended descriptors for third radio. */
 };
 
 /**
@@ -822,6 +826,9 @@
 struct nss_wifili_wds_peer_msg {
 	uint8_t dest_mac[ETH_ALEN];	/**< MAC address of the destination. */
 	uint8_t peer_mac[ETH_ALEN];	/**< MAC address of the base peer. */
+	uint8_t ast_type;		/**< AST (Address Search Table) type for this peer. */
+	uint8_t pdev_id;		/**< Radio ID for next hop peer. */
+	uint16_t peer_id;		/**< Peer ID of next hop peer. */
 };
 
 /**
diff --git a/nss_cmn.c b/nss_cmn.c
index 50c3834..4f887e5 100644
--- a/nss_cmn.c
+++ b/nss_cmn.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -40,7 +40,7 @@
 
 /*
  * nss_cmn_msg_init()
- *	Initialize the common message structure.
+ *	Initialize the common message of an ASYNC message.
  */
 void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type,  uint32_t len, void *cb, void *app_data)
 {
@@ -54,6 +54,16 @@
 EXPORT_SYMBOL(nss_cmn_msg_init);
 
 /*
+ * nss_cmn_msg_sync_init()
+ *	Initialize the common message of a SYNC message.
+ */
+void nss_cmn_msg_sync_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len)
+{
+	nss_cmn_msg_init(ncm, if_num, type, len, NULL, NULL);
+}
+EXPORT_SYMBOL(nss_cmn_msg_sync_init);
+
+/*
  * nss_cmn_get_interface_number()
  *	Return the interface number of the NSS net_device.
  *
diff --git a/nss_crypto.c b/nss_crypto.c
index 409c53d..7c9fa92 100644
--- a/nss_crypto.c
+++ b/nss_crypto.c
@@ -21,6 +21,7 @@
 
 #include "nss_tx_rx_common.h"
 #include "nss_crypto.h"
+#include "nss_crypto_log.h"
 
 /*
  **********************************
@@ -95,6 +96,11 @@
 	nss_core_log_msg_failures(nss_ctx, ncm);
 
 	/*
+	 * Trace messages.
+	 */
+	nss_crypto_log_rx_msg(nim);
+
+	/*
 	 * Load, Test & call
 	 */
 	cb = (nss_crypto_msg_callback_t)ncm->cb;
@@ -134,6 +140,11 @@
 	nss_info("msg params version:%d, interface:%d, type:%d, cb:%p, app_data:%p, len:%d\n",
 			ncm->version, ncm->interface, ncm->type, (void *)ncm->cb, (void *)ncm->app_data, ncm->len);
 
+	/*
+	 * Trace messages.
+	 */
+	nss_crypto_log_tx_msg(msg);
+
 	return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
 }
 
diff --git a/nss_crypto_log.c b/nss_crypto_log.c
new file mode 100644
index 0000000..8f22216
--- /dev/null
+++ b/nss_crypto_log.c
@@ -0,0 +1,151 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_crypto_log.c
+ *	NSS Crypto logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_crypto_log_message_types_str
+ *	Crypto message strings
+ */
+static int8_t *nss_crypto_log_message_types_str[NSS_CRYPTO_MSG_TYPE_MAX] __maybe_unused = {
+	"Crypto Invalid Message",
+	"Crypto Open Engine Message",
+	"Crypto Close Engine Message",
+	"Crypto Update Session",
+	"Crypto Stats Sync",
+};
+
+/*
+ * nss_crypto_log_error_response_types_str
+ *	Strings for error types for CRYPTO messages
+ */
+static int8_t *nss_crypto_log_error_response_types_str[NSS_CRYPTO_MSG_ERROR_MAX] __maybe_unused = {
+	"Crypto No Error",
+	"Crypto Invalid Engine",
+	"Crypto Unsupported Operation",
+	"Crypto Invalid Operation",
+	"Crypto Invalid Index Range",
+	"Crypto Index Alloc Failure",
+};
+
+/*
+ * nss_crypto_config_eng_msg()
+ *	Log NSS Crypto config engine message.
+ */
+static void nss_crypto_config_eng_msg(struct nss_crypto_msg *ncm)
+{
+	struct nss_crypto_config_eng *nccem __maybe_unused = &ncm->msg.eng;
+	nss_trace("%p: NSS Crypto Config Engine Message:\n"
+		"Crypto Engine Number: %d\n"
+		"Crypto BAM Physical Base Address: %x\n"
+		"Crypto Physical Base Address: %x\n"
+		"Crypto Pipe Description Address: %p\n"
+		"Crypto Session Indices: %p\n",
+		nccem, nccem->eng_id,
+		nccem->bam_pbase, nccem->crypto_pbase,
+		&nccem->desc_paddr, &nccem->idx);
+}
+
+/*
+ * nss_crypto_config_session_msg()
+ *	Log NSS Crypto config session message.
+ */
+static void nss_crypto_config_session_msg(struct nss_crypto_msg *ncm)
+{
+	struct nss_crypto_config_session *nccsm __maybe_unused = &ncm->msg.session;
+	nss_trace("%p: NSS Crypto Config Session message \n"
+		"Crypto Session Index: %d\n"
+		"Crypto Session State: %d\n"
+		"Crypto Session Initialization Vector Length: %d\n",
+		nccsm, nccsm->idx,
+		nccsm->state, nccsm->iv_len);
+}
+
+/*
+ * nss_crypto_log_verbose()
+ *	Log message contents.
+ */
+static void nss_crypto_log_verbose(struct nss_crypto_msg *ncm)
+{
+	switch (ncm->cm.type) {
+	case NSS_CRYPTO_MSG_TYPE_OPEN_ENG:
+		nss_crypto_config_eng_msg(ncm);
+		break;
+
+	case NSS_CRYPTO_MSG_TYPE_UPDATE_SESSION:
+		nss_crypto_config_session_msg(ncm);
+		break;
+
+	default:
+		nss_warning("%p: Invalid message type\n", ncm);
+		break;
+	}
+}
+
+/*
+ * nss_crypto_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_crypto_log_tx_msg(struct nss_crypto_msg *ncm)
+{
+	if (ncm->cm.type >= NSS_CRYPTO_MSG_TYPE_MAX) {
+		nss_warning("%p: Invalid message type\n", ncm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type]);
+	nss_crypto_log_verbose(ncm);
+}
+
+/*
+ * nss_crypto_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_crypto_log_rx_msg(struct nss_crypto_msg *ncm)
+{
+	if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", ncm);
+		return;
+	}
+
+	if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type,
+			nss_crypto_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response]);
+		goto verbose;
+	}
+
+	if (ncm->cm.error >= NSS_CRYPTO_MSG_ERROR_MAX) {
+		nss_warning("%p: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n",
+			ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+			ncm->cm.error);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n",
+		ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type],
+		ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+		ncm->cm.error, nss_crypto_log_error_response_types_str[ncm->cm.error]);
+
+verbose:
+	nss_crypto_log_verbose(ncm);
+}
diff --git a/nss_crypto_log.h b/nss_crypto_log.h
new file mode 100644
index 0000000..c0d53dd
--- /dev/null
+++ b/nss_crypto_log.h
@@ -0,0 +1,37 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_CRYPTO_LOG_H__
+#define __NSS_CRYPTO_LOG_H__
+
+/*
+ * nss_crypto_log.h
+ *	NSS Crypto Log Header File
+ */
+
+/*
+ * nss_crypto_log_tx_msg
+ *	Logs a crypto message that is sent to the NSS firmware.
+ */
+void nss_crypto_log_tx_msg(struct nss_crypto_msg *ncm);
+
+/*
+ * nss_crypto_log_rx_msg
+ *	Logs a crypto message that is received from the NSS firmware.
+ */
+void nss_crypto_log_rx_msg(struct nss_crypto_msg *ncm);
+
+#endif /* __NSS_CRYPTO_LOG_H__ */
diff --git a/nss_dynamic_interface.c b/nss_dynamic_interface.c
index fe27207..5431570 100644
--- a/nss_dynamic_interface.c
+++ b/nss_dynamic_interface.c
@@ -15,6 +15,7 @@
  */
 
 #include "nss_tx_rx_common.h"
+#include "nss_dynamic_interface_log.h"
 
 #define NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT 60000	/* 60 Sec */
 
@@ -60,6 +61,11 @@
 	nss_core_log_msg_failures(nss_ctx, ncm);
 
 	/*
+	 * Trace messages.
+	 */
+	nss_dynamic_interface_log_rx_msg(ndim);
+
+	/*
 	 * Handling dynamic interface messages coming from NSS fw.
 	 */
 	switch (ndim->cm.type) {
@@ -145,6 +151,11 @@
 		return NSS_TX_FAILURE;
 	}
 
+	/*
+	 * Trace messages.
+	 */
+	nss_dynamic_interface_log_tx_msg(msg);
+
 	return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
 }
 
diff --git a/nss_dynamic_interface_log.c b/nss_dynamic_interface_log.c
new file mode 100644
index 0000000..771215b
--- /dev/null
+++ b/nss_dynamic_interface_log.c
@@ -0,0 +1,145 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_dynamic_interface_log.c
+ *	NSS Dynamic Interface logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_dynamic_interface_log_message_types_str
+ *	Dynamic Interface message strings
+ */
+static int8_t *nss_dynamic_interface_log_message_types_str[NSS_DYNAMIC_INTERFACE_MAX] __maybe_unused = {
+	"Dynamic Interface Alloc Node",
+	"Dynamic Interface Dealloc Node"
+};
+
+/*
+ * nss_dynamic_interface_log_error_response_types_str
+ *	Strings for error types for dynamic interface messages
+ */
+static int8_t *nss_dynamic_interface_log_error_response_types_str[NSS_DYNAMIC_INTERFACE_ERR_MAX] __maybe_unused = {
+	"Dynamic Interface Error Unknown Interface",
+	"Dynamic Interface Error Unavailable Interface",
+	"Dynamic Interface Error Invalid Interface Type",
+	"Dynamic Interface Error Invalid Interface Number",
+	"Dynamic Interface Error Alloc Function Unavailable",
+	"Dynamic Interface Error Dealloc Funciton Unavailable",
+	"Dynamic Interface Error Allocation Error",
+	"Dynamic Interface Error Interface Number Mismatch"
+};
+
+/*
+ * nss_dynamic_interface_alloc_node_msg()
+ *	Log Dynamic Interface alloc node message.
+ */
+static void nss_dynamic_interface_alloc_node_log_msg(struct nss_dynamic_interface_msg *ndm)
+{
+	struct nss_dynamic_interface_alloc_node_msg *ndanm __maybe_unused = &ndm->msg.alloc_node;
+	nss_trace("%p: NSS Dynamic Interface Alloc Node Message:\n"
+		"Dynamic Interface Type: %d\n"
+		"Dynamic Interface Number: %d\n",
+		ndanm, ndanm->type,
+		ndanm->if_num);
+}
+
+/*
+ * nss_dynamic_interface_dealloc_node_msg()
+ *	Log Dynamic Interface dealloc node message.
+ */
+static void nss_dynamic_interface_dealloc_node_log_msg(struct nss_dynamic_interface_msg *ndm)
+{
+	struct nss_dynamic_interface_dealloc_node_msg *nddnm __maybe_unused = &ndm->msg.dealloc_node;
+	nss_trace("%p: NSS Dynamic Interface Alloc Node Message:\n"
+		"Dynamic Interface Type: %d\n"
+		"Dynamic Interface Number: %d\n",
+		nddnm, nddnm->type,
+		nddnm->if_num);
+}
+
+/*
+ * nss_dynamic_interface_log_verbose()
+ *	Log message contents.
+ */
+static void nss_dynamic_interface_log_verbose(struct nss_dynamic_interface_msg *ndm)
+{
+	switch (ndm->cm.type) {
+	case NSS_DYNAMIC_INTERFACE_ALLOC_NODE:
+		nss_dynamic_interface_alloc_node_log_msg(ndm);
+		break;
+
+	case NSS_DYNAMIC_INTERFACE_DEALLOC_NODE:
+		nss_dynamic_interface_dealloc_node_log_msg(ndm);
+		break;
+
+	default:
+		nss_warning("%p: Invalid message type\n", ndm);
+		break;
+	}
+}
+
+/*
+ * nss_dynamic_interface_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_dynamic_interface_log_tx_msg(struct nss_dynamic_interface_msg *ndm)
+{
+	if (ndm->cm.type >= NSS_DYNAMIC_INTERFACE_MAX) {
+		nss_warning("%p: Invalid message type\n", ndm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type]);
+	nss_dynamic_interface_log_verbose(ndm);
+}
+
+/*
+ * nss_dynamic_interface_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_dynamic_interface_log_rx_msg(struct nss_dynamic_interface_msg *ndm)
+{
+	if (ndm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", ndm);
+		return;
+	}
+
+	if (ndm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ndm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", ndm, ndm->cm.type,
+			nss_dynamic_interface_log_message_types_str[ndm->cm.type],
+			ndm->cm.response, nss_cmn_response_str[ndm->cm.response]);
+		goto verbose;
+	}
+
+	if (ndm->cm.error >= NSS_DYNAMIC_INTERFACE_ERR_MAX) {
+		nss_warning("%p: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n",
+			ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type],
+			ndm->cm.response, nss_cmn_response_str[ndm->cm.response],
+			ndm->cm.error);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s\n, error[%d]:%s\n",
+		ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type],
+		ndm->cm.response, nss_cmn_response_str[ndm->cm.response],
+		ndm->cm.error, nss_dynamic_interface_log_error_response_types_str[ndm->cm.error]);
+
+verbose:
+	nss_dynamic_interface_log_verbose(ndm);
+}
diff --git a/nss_dynamic_interface_log.h b/nss_dynamic_interface_log.h
new file mode 100644
index 0000000..266b909
--- /dev/null
+++ b/nss_dynamic_interface_log.h
@@ -0,0 +1,37 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_DYNAMIC_INTERFACE_LOG_H
+#define __NSS_DYNAMIC_INTERFACE_LOG_H
+
+/*
+ * nss_dynamic_interface.h
+ *	NSS Dynamic Interface private header file.
+ */
+
+/*
+ * nss_dynamic_interface_log_tx_msg
+ *	Logs a dynamic interface message that is sent to the NSS firmware.
+ */
+void nss_dynamic_interface_log_tx_msg(struct nss_dynamic_interface_msg *ndm);
+
+/*
+ * nss_dynamic_interface_log_rx_msg
+ *	Logs a dynamic interface message that is received from the NSS firmware.
+ */
+void nss_dynamic_interface_log_rx_msg(struct nss_dynamic_interface_msg *ndm);
+
+#endif /* __NSS_DYNAMIC_INTERFACE_LOG_H */
diff --git a/nss_gre_tunnel.c b/nss_gre_tunnel.c
index aa6aa22..435102b 100644
--- a/nss_gre_tunnel.c
+++ b/nss_gre_tunnel.c
@@ -16,6 +16,7 @@
 
 #include "nss_tx_rx_common.h"
 #include "nss_gre_tunnel_stats.h"
+#include "nss_gre_tunnel_log.h"
 
 #define NSS_GRE_TUNNEL_TX_TIMEOUT 3000 /* 3 Seconds */
 
@@ -65,6 +66,11 @@
 	BUG_ON(!nss_gre_tunnel_verify_if_num(ncm->interface));
 
 	/*
+	 * Trace Messages
+	 */
+	nss_gre_tunnel_log_rx_msg(ngtm);
+
+	/*
 	 * Is this a valid request/response packet?
 	 */
 	if (ncm->type >= NSS_GRE_TUNNEL_MSG_MAX) {
@@ -204,6 +210,10 @@
 {
 	struct nss_cmn_msg *ncm = &msg->cm;
 
+	/*
+	 * Trace Messages
+	 */
+	nss_gre_tunnel_log_tx_msg(msg);
 
 	/*
 	 * Sanity check message
diff --git a/nss_gre_tunnel_log.c b/nss_gre_tunnel_log.c
new file mode 100644
index 0000000..165eb9c
--- /dev/null
+++ b/nss_gre_tunnel_log.c
@@ -0,0 +1,168 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_gre_tunnel_log.c
+ *	NSS GRE Tunnel logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_gre_tunnel_log_message_types_str
+ *	NSS GRE Tunnel message strings
+ */
+static int8_t *nss_gre_tunnel_log_message_types_str[NSS_GRE_TUNNEL_MSG_MAX] __maybe_unused = {
+	"GRE Tunnel configure",
+	"GRE Tunnel session destroy",
+	"GRE Tunnel stats",
+	"GRE Tunnel configure DI to WLAN ID",
+	"GRE Tunnel message inquiry"
+};
+
+/*
+ * nss_gre_tunnel_log_configure_msg()
+ *	Log NSS GRE Tunnel configure message.
+ */
+static void nss_gre_tunnel_log_configure_msg(struct nss_gre_tunnel_msg *ngm)
+{
+	struct nss_gre_tunnel_configure *ngcm __maybe_unused = &ngm->msg.configure;
+	nss_trace("%p: NSS GRE Tunnel configure message \n"
+		"Meta Header Version: %d\n"
+		"GRE Mode: %x\n"
+		"IP Type: %x\n"
+		"Encryption Type: %d\n"
+		"Source Port: %d\n"
+		"Destination Port: %d\n"
+		"Crypto Node Identifier: %d\n"
+		"Encryption Crypto Index: %d\n"
+		"Decryption Crypto Index: %d\n"
+		"Word0 header: %d\n"
+		"Initialization Vector: %p\n"
+		"Sibling Interface Number: %d\n"
+		"TTL: %d\n"
+		"RPS: %d\n"
+		"Reserved: %x\n"
+		"Word1 Header: %x\n"
+		"Word2 Header: %x\n"
+		"Word3 Header: %x\n",
+		ngcm, ngcm->mh_version, ngcm->gre_mode,
+		ngcm->ip_type, ngcm->encrypt_type,
+		ngcm->src_port, ngcm->dest_port,
+		ngcm->crypto_node_id, ngcm->crypto_idx_encrypt,
+		ngcm->crypto_idx_decrypt, ngcm->word0,
+		ngcm->iv_val, ngcm->sibling_if,
+		ngcm->ttl, ngcm->rps,
+		ngcm->reserved, ngcm->word1,
+		ngcm->word2, ngcm->word3);
+
+	/*
+	 * Continuation of log message. Different identifiers based on ip_type
+	 */
+	if (ngcm->ip_type == NSS_GRE_TUNNEL_IP_IPV6) {
+		nss_trace("Source IP: %pI6\n"
+			"Destination IP: %pI6\n",
+			ngcm->src_ip, ngcm->dest_ip);
+	} else if (ngcm->ip_type == NSS_GRE_TUNNEL_IP_IPV4) {
+		nss_trace("Source IP: %pI4\n"
+			"Destination IP: %pI4\n",
+			ngcm->src_ip, ngcm->dest_ip);
+	}
+}
+
+/*
+ * nss_gre_tunnel_log_di_to_wlan_id_msg()
+ *	Log NSS GRE Tunnel Dynamic Interface to WLAN ID message.
+ */
+static void nss_gre_tunnel_log_di_to_wlan_id_msg(struct nss_gre_tunnel_msg *ngm)
+{
+	struct nss_gre_tunnel_di_to_wlan_id *ngdm __maybe_unused = &ngm->msg.dtwi;
+	nss_trace("%p: NSS GRE Dynamic Interface to WLAN ID message: \n"
+		"Dynamic Interface Number: %d\n"
+		"WLAN ID: %x\n",
+		ngdm, ngdm->dynamic_interface_num,
+		ngdm->wlan_id);
+}
+
+/*
+ * nss_gre_tunnel_log_verbose()
+ *	Log message contents.
+ */
+static void nss_gre_tunnel_log_verbose(struct nss_gre_tunnel_msg *ngm)
+{
+	switch (ngm->cm.type) {
+	case NSS_GRE_TUNNEL_MSG_CONFIGURE:
+	case NSS_GRE_TUNNEL_MSG_INQUIRY:
+		nss_gre_tunnel_log_configure_msg(ngm);
+		break;
+
+	case NSS_GRE_TUNNEL_MSG_CONFIGURE_DI_TO_WLAN_ID:
+		nss_gre_tunnel_log_di_to_wlan_id_msg(ngm);
+		break;
+
+	case NSS_GRE_TUNNEL_MSG_SESSION_DESTROY:
+	case NSS_GRE_TUNNEL_MSG_STATS:
+		/*
+		 * No log for these valid messages.
+		 */
+		break;
+
+	default:
+		nss_trace("%p: Invalid message type\n", ngm);
+		break;
+	}
+}
+
+/*
+ * nss_gre_tunnel_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_gre_tunnel_log_tx_msg(struct nss_gre_tunnel_msg *ngm)
+{
+	if (ngm->cm.type >= NSS_GRE_TUNNEL_MSG_MAX) {
+		nss_warning("%p: Invalid message type\n", ngm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_tunnel_log_message_types_str[ngm->cm.type]);
+	nss_gre_tunnel_log_verbose(ngm);
+}
+
+/*
+ * nss_gre_tunnel_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_gre_tunnel_log_rx_msg(struct nss_gre_tunnel_msg *ngm)
+{
+	if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", ngm);
+		return;
+	}
+
+	if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type,
+			nss_gre_tunnel_log_message_types_str[ngm->cm.type],
+			ngm->cm.response, nss_cmn_response_str[ngm->cm.response]);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s\n",
+		ngm, ngm->cm.type, nss_gre_tunnel_log_message_types_str[ngm->cm.type],
+		ngm->cm.response, nss_cmn_response_str[ngm->cm.response]);
+
+verbose:
+	nss_gre_tunnel_log_verbose(ngm);
+}
diff --git a/nss_gre_tunnel_log.h b/nss_gre_tunnel_log.h
new file mode 100644
index 0000000..be07513
--- /dev/null
+++ b/nss_gre_tunnel_log.h
@@ -0,0 +1,41 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_GRE_TUNNEL_LOG_H
+#define __NSS_GRE_TUNNEL_LOG_H
+
+/*
+ * nss_gre_tunnel.h
+ *	NSS GRE Tunnel header file.
+ */
+
+/*
+ * Logger APIs
+ */
+
+/*
+ * nss_gre_tunnel_log_tx_msg
+ *	Logs a gre_tunnel message that is sent to the NSS firmware.
+ */
+void nss_gre_tunnel_log_tx_msg(struct nss_gre_tunnel_msg *ngm);
+
+/*
+ * nss_gre_tunnel_log_rx_msg
+ *	Logs a gre_tunnel message that is received from the NSS firmware.
+ */
+void nss_gre_tunnel_log_rx_msg(struct nss_gre_tunnel_msg *ngm);
+
+#endif /* __NSS_GRE_TUNNEL_LOG_H */
diff --git a/nss_tx_msg_sync.c b/nss_tx_msg_sync.c
new file mode 100644
index 0000000..3766fdb
--- /dev/null
+++ b/nss_tx_msg_sync.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * nss_tx_msg_sync.c
+ *	NSS Tx msg sync core APIs
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_tx_msg_sync.h"
+
+/*
+ * nss_tx_msg_sync_callback()
+ *	Internal callback used to handle the message response.
+ */
+static void nss_tx_msg_sync_callback(void *app_data, struct nss_cmn_msg *ncm)
+{
+	uint32_t resp_offset;
+
+	/*
+	 * Per-message sync data was used as app_data.
+	 * Retrieve the address of the original message from it.
+	 */
+	struct nss_tx_msg_sync_cmn_data *sync_data = (struct nss_tx_msg_sync_cmn_data *)app_data;
+	struct nss_cmn_msg *original_msg = (struct nss_cmn_msg *)sync_data->original_msg;
+
+	/*
+	 * Set TX status. And Copy back ncm->error and ncm->response if it is NACK.
+	 */
+	sync_data->status = NSS_TX_SUCCESS;
+	if (ncm->response != NSS_CMN_RESPONSE_ACK) {
+		nss_warning("Tx msg sync error response %d\n", ncm->response);
+		sync_data->status = NSS_TX_FAILURE_SYNC_FW_ERR;
+		original_msg->error = ncm->error;
+		original_msg->response = ncm->response;
+	}
+
+	/*
+	 * ncm is the return message containing message response.
+	 * It is different from the original message caller built.
+	 * Because the return message is only visible in this callback context,
+	 * we copy back message response by specifying offset and length to
+	 * the return message. So the caller can use response in their context
+	 * once wake up instead of calling a passed-in user callback here.
+	 */
+	resp_offset = sync_data->resp_offset + sizeof(struct nss_cmn_msg);
+
+	if (sync_data->copy_len > 0)
+		memcpy((uint8_t *)((nss_ptr_t)original_msg + resp_offset),
+			(uint8_t *)((nss_ptr_t)ncm + resp_offset),
+			sync_data->copy_len);
+
+	/*
+	 * Wake up the caller
+	 */
+	complete(&sync_data->complete);
+}
+
+/*
+ * nss_tx_msg_sync_internal()
+ *	Internal call for sending messages to FW synchronously.
+ */
+static nss_tx_status_t nss_tx_msg_sync_internal(struct nss_ctx_instance *nss_ctx,
+						nss_tx_msg_sync_subsys_async_t tx_msg_async,
+						struct nss_tx_msg_sync_cmn_data *sync_data,
+						struct nss_cmn_msg *ncm,
+						uint32_t timeout)
+{
+	nss_tx_status_t status;
+	int ret;
+
+	/*
+	 * Per-msg sync data is used as app_data.
+	 * A generic callback is used to handle the return message.
+	 */
+	ncm->cb = (nss_ptr_t)nss_tx_msg_sync_callback;
+	ncm->app_data = (nss_ptr_t)sync_data;
+
+	/*
+	 * Per-subsystem asynchronous call to send down the message.
+	 */
+	status = tx_msg_async(nss_ctx, ncm);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: Tx msg async failed\n", nss_ctx);
+		return status;
+	}
+
+	/*
+	 * Sleep. Wake up either by notification or timeout.
+	 */
+	ret = wait_for_completion_timeout(&sync_data->complete, msecs_to_jiffies(timeout));
+	if (!ret) {
+		nss_warning("%p: Tx msg sync timeout\n", nss_ctx);
+		return NSS_TX_FAILURE_SYNC_TIMEOUT;
+	}
+
+	/*
+	 * Wake up. Message response has been received within timeout.
+	 */
+	return sync_data->status;
+}
+
+/*
+ * nss_tx_msg_sync()
+ *	Core function to send messages to FW synchronously.
+ *
+ * tx_msg_async specifies the per-subsystem asynchronous call.
+ * timeout specifies the maximum sleep time for the completion.
+ * ncm is the original message the caller built.
+ * Since the caller cannot access the return message containing message response,
+ * we copy back message response from return message.
+ * resp_offset and copy_len specify the part of return message it'll copy.
+ */
+nss_tx_status_t nss_tx_msg_sync(struct nss_ctx_instance *nss_ctx,
+				nss_tx_msg_sync_subsys_async_t tx_msg_async,
+				uint32_t timeout, struct nss_cmn_msg *ncm,
+				uint32_t resp_offset, uint32_t copy_len)
+{
+	struct nss_tx_msg_sync_cmn_data sync_data;
+
+	NSS_VERIFY_CTX_MAGIC(nss_ctx);
+
+	/*
+	 * Check Tx msg async API
+	 */
+	if (!unlikely(tx_msg_async)) {
+		nss_warning("%p: missing Tx msg async API\n", nss_ctx);
+		return NSS_TX_FAILURE_SYNC_BAD_PARAM;
+	}
+
+	/*
+	 * Initialize the per-message sync data.
+	 */
+	init_completion(&sync_data.complete);
+	sync_data.status = NSS_TX_FAILURE;
+	sync_data.original_msg = (void *)ncm;
+	sync_data.resp_offset = resp_offset;
+	sync_data.copy_len = copy_len;
+
+	return nss_tx_msg_sync_internal(nss_ctx, tx_msg_async, &sync_data, ncm, timeout);
+}
+EXPORT_SYMBOL(nss_tx_msg_sync);
diff --git a/nss_tx_msg_sync.h b/nss_tx_msg_sync.h
new file mode 100644
index 0000000..724d2d7
--- /dev/null
+++ b/nss_tx_msg_sync.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * nss_tx_msg_sync.h
+ *	NSS Tx msg sync header file
+ */
+
+#ifndef __NSS_TX_MSG_SYNC_H
+#define __NSS_TX_MSG_SYNC_H
+
+#include <nss_core.h>
+
+/*
+ * Per-message sync data
+ *	Used as message app_data.
+ */
+struct nss_tx_msg_sync_cmn_data {
+	struct completion complete;	/* Completion structure */
+	nss_tx_status_t status;		/* Tx status */
+	void *original_msg;		/* Address of the caller-build message */
+	uint32_t resp_offset;		/* Response offset in message payload */
+	uint32_t copy_len;		/* Length in bytes copied from the return message */
+};
+
+/*
+ * nss_tx_msg_sync_subsys_async_t()
+ *	Tx msg asynchronous API of each subsystem.
+ */
+typedef nss_tx_status_t (*nss_tx_msg_sync_subsys_async_t)(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm);
+
+/*
+ * nss_tx_msg_sync()
+ *	Core function to send message to FW synchronously.
+ *
+ * tx_msg_async specifies the per-subsystem asynchronous call.
+ * timeout specifies the maximum sleep time for the completion.
+ * ncm is the original message the caller built.
+ * Since the caller cannot access the return message containing message response,
+ * we copy back message response from the return message.
+ * resp_offset and copy_len specify the part of return message it'll copy.
+ */
+nss_tx_status_t nss_tx_msg_sync(struct nss_ctx_instance *nss_ctx,
+				nss_tx_msg_sync_subsys_async_t tx_msg_async,
+				uint32_t timeout, struct nss_cmn_msg *ncm,
+				uint32_t resp_offset, uint32_t copy_len);
+
+#endif /* __NSS_TX_MSG_SYNC_H */
diff --git a/nss_wifi.c b/nss_wifi.c
index cffd3d3..ca60fd6 100644
--- a/nss_wifi.c
+++ b/nss_wifi.c
@@ -16,6 +16,7 @@
 
 #include "nss_tx_rx_common.h"
 #include "nss_wifi_stats.h"
+#include "nss_wifi_log.h"
 
 /*
  * nss_wifi_get_context()
@@ -41,6 +42,11 @@
 	BUG_ON(((ncm->interface < NSS_WIFI_INTERFACE0) || (ncm->interface > NSS_WIFI_INTERFACE2)));
 
 	/*
+	 * Trace messages.
+	 */
+	nss_wifi_log_rx_msg(ntm);
+
+	/*
 	 * Is this a valid request/response packet?
 	 */
 	if (ncm->type >= NSS_WIFI_MAX_MSG) {
@@ -111,6 +117,11 @@
 {
 	struct nss_cmn_msg *ncm = &msg->cm;
 
+	/*
+	 * Trace messages.
+	 */
+	nss_wifi_log_tx_msg(msg);
+
 	if (ncm->type > NSS_WIFI_MAX_MSG) {
 		nss_warning("%p: wifi message type out of range: %d", nss_ctx, ncm->type);
 		return NSS_TX_FAILURE;
diff --git a/nss_wifi_log.c b/nss_wifi_log.c
new file mode 100644
index 0000000..19ce0dc
--- /dev/null
+++ b/nss_wifi_log.c
@@ -0,0 +1,806 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_wifi_log.c
+ *	NSS WIFI logger file.
+ */
+
+#include "nss_core.h"
+
+/*
+ * nss_wifi_log_message_types_str
+ *	WIFI message strings
+ */
+static int8_t *nss_wifi_log_message_types_str[NSS_WIFI_MAX_MSG] __maybe_unused = {
+	"WIFI INIT MSG",
+	"WIFI POST RECV MSG",
+	"WIFI HTT INIT MSG",
+	"WIFI TX INIT MSG",
+	"WIFI RAW SEND MSG",
+	"WIFI MGMT SEND MSG",
+	"WIFI WDS PEER ADD MSG",
+	"WIFI WDS PEER DEL MSG",
+	"WIFI STOP MSG",
+	"WIFI RESET MSG",
+	"WIFI STATS MSG",
+	"WIFI PEER FREELIST APPEND MSG",
+	"WIFI RX REORDER ARRAY FREELIST APPEND MSG",
+	"WIFI SEND PEER MEMORY REQUEST MSG",
+	"WIFI SEND RRA MEMORY REQUEST MSG",
+	"WIFI FW STATS MSG",
+	"WIFI MONITOR FILTER SET MSG",
+	"WIFI PEER BS STATE MSG",
+	"WIFI MSDU TTL SET MSG",
+	"WIFI RX VOW EXTSTATS SET MSG",
+	"WIFI PKTLOG CFG MSG",
+	"WIFI ENABLE PERPKT TXSTATS MSG",
+	"WIFI IGMP MLD TOS OVERRIDE MSG",
+	"WIFI OL STATS CFG MSG",
+	"WIFI OL STATS MSG",
+	"WIFI TX QUEUE CFG MSG",
+	"WIFI TX MIN THRESHOLD CFG MSG",
+	"WIFI DBDC PROCESS ENABLE MSG",
+	"WIFI PRIMARY RADIO SET MSG",
+	"WIFI FORCE CLIENT MCAST TRAFFIC SET MSG",
+	"WIFI STORE OTHER PDEV STAVAP MSG",
+	"WIFI STA KICKOUT MSG",
+	"WIFI WNM PEER RX ACTIVITY MSG",
+	"WIFI PEER STATS MSG",
+	"WIFI WDS VENDOR MSG",
+	"WIFI TX CAPTURE SET MSG",
+	"WIFI ALWAYS PRIMARY SET MSG",
+	"WIFI FLUSH HTT CMD MSG",
+	"WIFI CMD MSG",
+	"WIFI ENABLE OL STATSV2 MSG",
+	"WIFI OL PEER TIME MSG",
+};
+
+/*
+ * nss_wifi_log_error_response_types_str
+ *	Strings for error types for WIFI messages
+ */
+static int8_t *nss_wifi_log_error_response_types_str[NSS_WIFI_EMSG_MAX] __maybe_unused = {
+	"WIFI NO ERROR",
+	"WIFI UNKNOWN MSG",
+	"WIFI MGMT DLEN",
+	"WIFI MGMT SEND",
+	"WIFI CE INIT FAIL",
+	"WIFI PDEV INIT FAIL",
+	"WIFI HTT INIT FAIL",
+	"WIFI PEER ADD",
+	"WIFI WIFI START FAIL",
+	"WIFI STATE NOT RESET",
+	"WIFI STATE NOT INIT DONE",
+	"WIFI STATE NULL CE HANDLE",
+	"WIFI STATE NOT CE READY",
+	"WIFI STATE NOT HTT READY",
+	"WIFI FW STATS DLEN",
+	"WIFI FW STATS SEND",
+	"WIFI STATE TX INIT FAILED",
+	"WIFI IGMP MLD TOS OVERRIDE CFG",
+	"WIFI PDEV INVALID",
+	"WIFI OTHER PDEV STAVAP INVALID",
+	"WIFI HTT SEND FAIL",
+	"WIFI CE RING INIT",
+	"WIFI NOTIFY CB",
+	"WIFI PEERID INVALID",
+	"WIFI PEER INVALID",
+	"WIFI UNKNOWN CMD"
+};
+
+/*
+ * nss_wifi_log_init_msg()
+ *	Log NSS WIFI Init message.
+ */
+static void nss_wifi_log_init_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_init_msg *nwim __maybe_unused = &ncm->msg.initmsg;
+
+	nss_trace("%p: NSS WIFI Init Message:\n"
+		"WIFI Radio ID: %d\n"
+		"WIFI PCI Memory Address: %x\n"
+		"WIFI Target Type: %d\n"
+		"WIFI MU MIMO Enhancement Enable Flag: %d\n"
+		"WIFI Transmit Copy Engine Source Ring:\n"
+		"\tNumber of Entries: %d\n"
+		"\tNumber of Entries Mask: %x\n"
+		"\tInitial Software Index: %d\n"
+		"\tInitial Write Index: %d\n"
+		"\tInitial Hardware Index: %d\n"
+		"\tPhysical Address: %x\n"
+		"\tVirtual Address: %x\n"
+		"WIFI Transmit Copy Engine Dest Ring:\n"
+		"\tNumber of Entries: %d\n"
+		"\tNumber of Entries Mask: %x\n"
+		"\tInitial Software Index: %d\n"
+		"\tInitial Write Index: %d\n"
+		"\tInitial Hardware Index: %d\n"
+		"\tPhysical Address: %x\n"
+		"\tVirtual Address: %x\n"
+		"WIFI Transmit Control Address of PCIe Bar: %x\n"
+		"WIFI Receive Copy Engine Source Ring:\n"
+		"\tNumber of Entries: %d\n"
+		"\tNumber of Entries Mask: %x\n"
+		"\tInitial Software Index: %d\n"
+		"\tInitial Write Index: %d\n"
+		"\tInitial Hardware Index: %d\n"
+		"\tPhysical Address: %x\n"
+		"\tVirtual Address: %x\n"
+		"WIFI Receive Copy Engine Dest Ring:\n"
+		"\tNumber of Entries: %d\n"
+		"\tNumber of Entries Mask: %x\n"
+		"\tInitial Software Index: %d\n"
+		"\tInitial Write Index: %d\n"
+		"\tInitial Hardware Index: %d\n"
+		"\tPhysical Address: %x\n"
+		"\tVirtual Address: %x\n"
+		"WIFI Receive Control Address of PCIe Bar: %x\n"
+		"WIFI Bypass Network Process: %d",
+		nwim, nwim->radio_id,
+		nwim->pci_mem, nwim->target_type,
+		nwim->mu_mimo_enhancement_en, nwim->ce_tx_state.src_ring.nentries,
+		nwim->ce_tx_state.src_ring.nentries_mask, nwim->ce_tx_state.src_ring.sw_index,
+		nwim->ce_tx_state.src_ring.write_index, nwim->ce_tx_state.src_ring.hw_index,
+		nwim->ce_tx_state.src_ring.base_addr_CE_space, nwim->ce_tx_state.src_ring.base_addr_owner_space,
+		nwim->ce_tx_state.dest_ring.nentries, nwim->ce_tx_state.dest_ring.nentries_mask,
+		nwim->ce_tx_state.dest_ring.sw_index, nwim->ce_tx_state.dest_ring.write_index,
+		nwim->ce_tx_state.dest_ring.hw_index, nwim->ce_tx_state.dest_ring.base_addr_CE_space,
+		nwim->ce_tx_state.dest_ring.base_addr_owner_space, nwim->ce_tx_state.ctrl_addr,
+		nwim->ce_rx_state.src_ring.nentries, nwim->ce_rx_state.src_ring.nentries_mask,
+		nwim->ce_rx_state.src_ring.sw_index, nwim->ce_rx_state.src_ring.write_index,
+		nwim->ce_rx_state.src_ring.hw_index, nwim->ce_rx_state.src_ring.base_addr_CE_space,
+		nwim->ce_rx_state.src_ring.base_addr_owner_space, nwim->ce_rx_state.dest_ring.nentries,
+		nwim->ce_rx_state.dest_ring.nentries_mask, nwim->ce_rx_state.dest_ring.sw_index,
+		nwim->ce_rx_state.dest_ring.write_index, nwim->ce_rx_state.dest_ring.hw_index,
+		nwim->ce_rx_state.dest_ring.base_addr_CE_space, nwim->ce_rx_state.dest_ring.base_addr_owner_space,
+		nwim->ce_rx_state.ctrl_addr, nwim->bypass_nw_process);
+}
+
+/*
+ * nss_wifi_log_stop_msg()
+ *	Log NSS WIFI Init message.
+ */
+static void nss_wifi_log_stop_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_stop_msg *nwsm __maybe_unused = &ncm->msg.stopmsg;
+	nss_trace("%p: NSS WIFI Init Message:\n"
+		"WIFI Radio ID: %d\n",
+		nwsm, nwsm->radio_id);
+}
+
+/*
+ * nss_wifi_log_reset_msg()
+ *	Log NSS WIFI Init message.
+ */
+static void nss_wifi_log_reset_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_reset_msg *nwrm __maybe_unused = &ncm->msg.resetmsg;
+	nss_trace("%p: NSS WIFI Init Message:\n"
+		"WIFI Radio ID: %d\n",
+		nwrm, nwrm->radio_id);
+}
+
+/*
+ * nss_wifi_log_htt_init_msg()
+ *	Log NSS WIFI HTT Init message.
+ */
+static void nss_wifi_log_htt_init_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_htt_init_msg *nwim __maybe_unused = &ncm->msg.httinitmsg;
+	nss_trace("%p: NSS WIFI HTT Init Message:\n"
+		"WIFI Radio ID: %d\n"
+		"WIFI Ring Size: %d\n"
+		"WIFI Fill Level: %d\n"
+		"WIFI MAC Hardware Ring Phy Address: %x\n"
+		"WIFI MAC Hardware Ring Virtual Address: %x\n"
+		"WIFI Hardware Ring Index Phy Address: %x\n"
+		"WIFI Hardware Ring Index Virtual Address: %x\n",
+		nwim, nwim->radio_id,
+		nwim->ringsize, nwim->fill_level,
+		nwim->paddrs_ringptr, nwim->paddrs_ringpaddr,
+		nwim->alloc_idx_paddr, nwim->alloc_idx_vaddr);
+}
+
+/*
+ * nss_wifi_log_tx_init_msg()
+ *	Log NSS TX HTT Init message.
+ */
+static void nss_wifi_log_tx_init_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_tx_init_msg *nwim __maybe_unused = &ncm->msg.pdevtxinitmsg;
+	nss_trace("%p: NSS WIFI HTT Init Message:\n"
+		"WIFI Radio ID: %d\n"
+		"WIFI Number of Descriptor Pools Allocated: %d\n"
+		"WIFI TX Descriptor Array: %x\n"
+		"WIFI MAC extenstion descriptor Address: %x\n"
+		"WIFI WLAN MAC extenstion descriptor size: %d\n"
+		"WIFI HTT Tx descriptor memory start virtual address: %x\n"
+		"WIFI HTT Tx descriptor memory base virtual address: %x\n"
+		"WIFI HTT Tx descriptor memory offset: %x\n"
+		"WIFI Firmware shared TID map: %x\n",
+		nwim, nwim->radio_id,
+		nwim->desc_pool_size, nwim->tx_desc_array,
+		nwim->wlanextdesc_addr, nwim->wlanextdesc_size,
+		nwim->htt_tx_desc_base_vaddr, nwim->htt_tx_desc_base_paddr,
+		nwim->htt_tx_desc_offset, nwim->pmap_addr);
+}
+
+/*
+ * nss_wifi_log_rawsend_msg()
+ *	Log NSS WIFI RAW Send message.
+ */
+static void nss_wifi_log_rawsend_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_rawsend_msg *nwrm __maybe_unused = &ncm->msg.rawmsg;
+	nss_trace("%p: NSS WIFI RAW Send Message:\n"
+		"WIFI Radio ID: %d\n"
+		"WIFI Size of Raw Data: %d\n"
+		"WIFI Raw Data: %p",
+		nwrm, nwrm->radio_id,
+		nwrm->len, nwrm->array);
+}
+
+/*
+ * nss_wifi_log_mgmtsend_msg()
+ *	Log NSS WIFI Management Send message.
+ */
+static void nss_wifi_log_mgmtsend_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_mgmtsend_msg *nwmm __maybe_unused = &ncm->msg.mgmtmsg;
+	nss_trace("%p: NSS WIFI Management Send Message:\n"
+		"WIFI Descriptor ID: %d\n"
+		"WIFI Size of Management Data: %d\n"
+		"WIFI Management Data: %p",
+		nwmm, nwmm->desc_id,
+		nwmm->len, nwmm->array);
+}
+
+/*
+ * nss_wifi_log_wds_peer_msg()
+ *	Log NSS WIFI WDS Peer message.
+ */
+static void nss_wifi_log_wds_peer_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_wds_peer_msg *nwmm __maybe_unused = &ncm->msg.pdevwdspeermsg;
+	nss_trace("%p: NSS WIFI WDS Peer Message:\n"
+		"WIFI Dest MAC: %pM\n"
+		"WIFI Peer MAC: %pM\n",
+		nwmm, nwmm->dest_mac,
+		nwmm->peer_mac);
+}
+
+/*
+ * nss_wifi_log_peer_freelist_append_msg()
+ *	Log NSS WIFI Create/Append Freelist message
+ */
+static void nss_wifi_log_peer_freelist_append_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_peer_freelist_append_msg *nwpm __maybe_unused = &ncm->msg.peer_freelist_append;
+	nss_trace("%p: NSS WIFI Create/Append Freelist Message:\n"
+		"WIFI Starting Address of Peer Freelist Pool: %x\n"
+		"WIFI Length of freelist pool: %d\n"
+		"WIFI Number of Peers supported in freelist pool: %d\n",
+		nwpm, nwpm->addr,
+		nwpm->length, nwpm->num_peers);
+}
+
+/*
+ * nss_wifi_log_rx_reorder_array_freelist_append_msg()
+ *	Log NSS WIFI RX Reorder Array Freelist message
+ */
+static void nss_wifi_log_rx_reorder_array_freelist_append_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_rx_reorder_array_freelist_append_msg *nwpm __maybe_unused = &ncm->msg.rx_reorder_array_freelist_append;
+	nss_trace("%p: NSS WIFI RX Reorder Array Freelist Message:\n"
+		"WIFI Starting Address of TIDQ Freelist Pool: %x\n"
+		"WIFI Length of TIDQ freelist pool: %d\n"
+		"WIFI Number of Rx reorder array entries supported in freelist pool: %d\n",
+		nwpm, nwpm->addr,
+		nwpm->length, nwpm->num_rra);
+}
+
+/*
+ * nss_wifi_log_set_filter_msg()
+ *	Log NSS WIFI Set Filter message
+ */
+static void nss_wifi_log_set_filter_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_monitor_set_filter_msg *nwfm __maybe_unused = &ncm->msg.monitor_filter_msg;
+	nss_trace("%p: NSS WIFI Set Filter Message:\n"
+		"WIFI Filter Type: %dn",
+		nwfm, nwfm->filter_type);
+}
+
+/*
+ * nss_wifi_log_peer_activity_msg()
+ *	Log NSS WIFI Get Active Peer for Radio message
+ */
+static void nss_wifi_log_peer_activity_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_bs_peer_activity *nwpm __maybe_unused = &ncm->msg.peer_activity;
+	nss_trace("%p: NSS WIFI Get Active Peer Message:\n"
+		"WIFI Number of Entries in Peer ID Array: %d\n"
+		"WIFI PEER ID: %d\n",
+		nwpm, nwpm->nentries,
+		nwpm->peer_id[0]);
+}
+
+/*
+ * nss_wifi_rx_vow_extstats_set_msg()
+ *	Log NSS WIFI VoW Extended Statistics Set Message.
+ */
+static void nss_wifi_log_rx_vow_extstats_set_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_rx_vow_extstats_set_msg *nwpm __maybe_unused = &ncm->msg.vow_extstats_msg;
+	nss_trace("%p: NSS WIFI VoW Extended Statistics Set Message:\n"
+		"WIFI VoW Extended Statistics Enable:: %d\n",
+		nwpm, nwpm->vow_extstats_en);
+}
+
+/*
+ * nss_wifi_log_pktlog_cfg_msg()
+ *	Log NSS WIFI Packet Log Configuration Message.
+ */
+static void nss_wifi_log_pktlog_cfg_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_pktlog_cfg_msg *nwpm __maybe_unused = &ncm->msg.pcm_msg;
+	nss_trace("%p: NSS WIFI Packet Log Configuration Message:\n"
+		"WIFI Packet Log Enable: %d\n"
+		"WIFI PAcket Log buffer Size: %d\n"
+		"WIFI Size of packet log header: %d\n"
+		"WIFI Offset for the MSDU ID: %d\n",
+		nwpm, nwpm->enable,
+		nwpm->bufsize, nwpm->hdrsize,
+		nwpm->msdu_id_offset);
+}
+
+/*
+ * nss_wifi_log_enable_perpkt_txstats_msg()
+ *	Log NSS WIFI Enable TX Stats Message.
+ */
+static void nss_wifi_log_enable_perpkt_txstats_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_enable_perpkt_txstats_msg *nwpm __maybe_unused = &ncm->msg.ept_msg;
+	nss_trace("%p: NSS WIFI Enable TX Stats Message:\n"
+		"WIFI TX Stats Enable Flag: %d\n",
+		nwpm, nwpm->perpkt_txstats_flag);
+}
+
+/*
+ * nss_wifi_log_override_tos_msg()
+ *	Log NSS WIFI Override TOS Message.
+ */
+static void nss_wifi_log_override_tos_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_igmp_mld_override_tos_msg *nwpm __maybe_unused = &ncm->msg.wigmpmldtm_msg;
+	nss_trace("%p: NSS WIFI Override TOS Message:\n"
+		"WIFI enable TID override Flag: %d\n"
+		"WIFI Value of TID to be overriden: %d\n",
+		nwpm, nwpm->igmp_mld_ovride_tid_en,
+		nwpm->igmp_mld_ovride_tid_val);
+}
+
+/*
+ * nss_wifi_log_ol_stats_cfg_msg()
+ *	Log NSS WIFI Offload Stats Config Message.
+ */
+static void nss_wifi_log_ol_stats_cfg_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_ol_stats_cfg_msg *nwpm __maybe_unused = &ncm->msg.scm_msg;
+	nss_trace("%p: NSS WIFI Enable/Disable Offload Stats Message:\n"
+		"WIFI enable/disable offload stats config: %d\n",
+		nwpm, nwpm->stats_cfg);
+}
+
+/*
+ * nss_wifi_log_tx_queue_cfg_msg()
+ *	Log NSS WIFI TX Queue Configuration message.
+ */
+static void nss_wifi_log_tx_queue_cfg_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_tx_queue_cfg_msg *nwpm __maybe_unused = &ncm->msg.wtxqcm;
+	nss_trace("%p: NSS WIFI TX Queue Config Message:\n"
+		"WIFI TX Queue Size: %d\n"
+		"WIFI TX Queue Range: %d\n",
+		nwpm, nwpm->size, nwpm->range);
+}
+
+/*
+ * nss_wifi_log_tx_min_threshold_cfg()
+ *	Log NSS WIFI TX Queue Min Threshold Configuration message.
+ */
+static void nss_wifi_log_tx_min_threshold_cfg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_tx_min_threshold_cfg_msg *nwpm __maybe_unused = &ncm->msg.wtx_min_threshold_cm;
+	nss_trace("%p: NSS WIFI TX Queue Min Threshold Config Message:\n"
+		"WIFI TX Queue Min Threshold Value: %d\n",
+		nwpm, nwpm->min_threshold);
+}
+
+/*
+ * nss_wifi_log_dbdc_process_enable_msg()
+ *	Log NSS WIFI DBDC repeater process configuration.
+ */
+static void nss_wifi_log_dbdc_process_enable_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_dbdc_process_enable_msg *nwpm __maybe_unused = &ncm->msg.dbdcpe_msg;
+	nss_trace("%p: NSS WIFI DBDC repeater process configuration:\n"
+		"WIFI DBDC Process Enable Flag: %d\n",
+		nwpm, nwpm->dbdc_process_enable);
+}
+
+/*
+ * nss_wifi_log_primary_radio_set_msg()
+ *	Log NSS WIFI Primary Radio Set message.
+ */
+static void nss_wifi_log_primary_radio_set_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_primary_radio_set_msg *nwpm __maybe_unused = &ncm->msg.wprs_msg;
+	nss_trace("%p: NSS WIFI Primary Radio Set Message:\n"
+		"WIFI Current Radio as Primary Radio Enable/Disable Flag: %d\n",
+		nwpm, nwpm->flag);
+}
+
+/*
+ * nss_wifi_log_force_client_mcast_traffic_set_msg()
+ *	Log NSS WIFI Force Multicat Traffic for Radio
+ */
+static void nss_wifi_log_force_client_mcast_traffic_set_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_force_client_mcast_traffic_set_msg *nwpm __maybe_unused = &ncm->msg.wfcmts_msg;
+	nss_trace("%p: NSS WIFI Force Multicat Traffic for Radio Message:\n"
+		"WIFI Radio Multicast Traffic Flag: %d\n",
+		nwpm, nwpm->flag);
+}
+
+/*
+ * nss_wifi_log_store_other_pdev_stavap_msg()
+ *	Log NSS WIFI Store Other Radio Station VAP Message.
+ */
+static void nss_wifi_log_store_other_pdev_stavap_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_store_other_pdev_stavap_msg *nwpm __maybe_unused = &ncm->msg.wsops_msg;
+	nss_trace("%p: NSS WIFI Store Other Radio Station VAP Message:\n"
+		"WIFI Station VAP Interface Number: %d\n",
+		nwpm, nwpm->stavap_ifnum);
+}
+
+/*
+ * nss_wifi_log_sta_kickout_msg()
+ *	Log NSS WIFI Station Kickout Message.
+ */
+static void nss_wifi_log_sta_kickout_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_sta_kickout_msg *nwpm __maybe_unused = &ncm->msg.sta_kickout_msg;
+	nss_trace("%p: NSS WIFI Station Kickout Message:\n"
+		"WIFI PEER ID: %d\n",
+		nwpm, nwpm->peer_id);
+}
+
+/*
+ * nss_wifi_log_wnm_peer_rx_activity()
+ *	Log NSS WIFI RX Active State Information of Peer.
+ */
+static void nss_wifi_log_wnm_peer_rx_activity(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_wnm_peer_rx_activity_msg *nwpm __maybe_unused = &ncm->msg.wprm;
+	nss_trace("%p: NSS WIFI RX Active State Information of Peer:\n"
+		"WIFI Peer ID: %p\n"
+		"WIFI Number of Entries: %d\n",
+		nwpm, nwpm->peer_id, nwpm->nentries);
+}
+
+/*
+ * nss_wifi_log_wds_extn_peer_cfg_msg()
+ *	Log NSS WIFI WDS Extension Enabled Configuraion Message.
+ */
+static void nss_wifi_log_wds_extn_peer_cfg_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_wds_extn_peer_cfg_msg *nwpm __maybe_unused = &ncm->msg.wpeercfg;
+	nss_trace("%p: NSS WIFI Extension Enabled Configuraion Message:\n"
+		"WIFI Peer MAC Address: %pM\n"
+		"WIFI WDS Flags: %d\n"
+		"WIFI Peer ID: %d\n",
+		nwpm, nwpm->mac_addr, nwpm->wds_flags,
+		nwpm->peer_id);
+}
+
+/*
+ * nss_wifi_log_tx_capture_msg()
+ *	Log NSS WIFI Enable TX Capture Message.
+ */
+static void nss_wifi_log_tx_capture_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_tx_capture_msg *nwpm __maybe_unused = &ncm->msg.tx_capture_msg;
+	nss_trace("%p: NSS WIFI Enable TX Capture Message:\n"
+		"WIFI TX Capture Enable Flag: %d\n",
+		nwpm, nwpm->tx_capture_enable);
+}
+
+/*
+ * nss_wifi_log_always_primary_set_msg()
+ *	Log NSS WIFI Always Set Current Radio Primary Message.
+ */
+static void nss_wifi_log_always_primary_set_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_always_primary_set_msg *nwpm __maybe_unused = &ncm->msg.waps_msg;
+	nss_trace("%p: NSS WIFI Always Set Current Radio Primary Message:\n"
+		"WIFI Always Set Flag: %d\n",
+		nwpm, nwpm->flag);
+}
+
+/*
+ * nss_wifi_log_cmd_msg()
+ *	Log NSS WIFI PDEV Command Message.
+ */
+static void nss_wifi_log_cmd_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_cmd_msg *nwpm __maybe_unused = &ncm->msg.wcmdm;
+	nss_trace("%p: NSS WIFI PDEV Command Message:\n"
+		"WIFI Type of Command: %d\n"
+		"WIFI Value of Command: %d\n",
+		nwpm, nwpm->cmd, nwpm->value);
+}
+
+/*
+ * nss_wifi_log_enable_ol_statsv2_msg()
+ *	Log NSS WIFI Enable Version 2 of TX/RX Stats
+ */
+static void nss_wifi_log_enable_ol_statsv2_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_enable_ol_statsv2 *nwpm __maybe_unused = &ncm->msg.wesh_msg;
+	nss_trace("%p: NSS WIFI Enable Version 2 of TX/RX Stats:\n"
+		"WIFI Enable Version 2 Stats: %d\n",
+		nwpm, nwpm->enable_ol_statsv2);
+}
+
+/*
+ * nss_wifi_log_enable_ol_peer_time_msg()
+ *	Log NSS WIFI Enable Per Peer Stats to Host
+ */
+static void nss_wifi_log_enable_ol_peer_time_msg(struct nss_wifi_msg *ncm)
+{
+	struct nss_wifi_ol_peer_time_msg *nwpm __maybe_unused = &ncm->msg.wopt_msg;
+	int32_t i;
+
+	nss_trace("%p: NSS WIFI Enable Per PEer Stats to Host:\n"
+		"WIFI Number of Peers: %d\n"
+		"WIFI Peed ID: %d\n",
+		nwpm, nwpm->npeers,
+		nwpm->tstats[0].peer_id);
+	/*
+	 * Continuation of the log.
+	 */
+	nss_trace("WIFI TX Timestamp:\n");
+	nss_trace("\tSum of sojourn for each packet:");
+	for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) {
+		nss_trace("\t\t%d = %x", i, nwpm->tstats[0].sum[i].sum_tx);
+	}
+	nss_trace("\tNumber of MSDU per peer per TID:");
+	for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) {
+		nss_trace("\t\t%d = %x", i, nwpm->tstats[0].sum[i].sum_msdus);
+	}
+	nss_trace("WIFI Exponential Weighted Average:");
+	for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) {
+		nss_trace("\t%d = %d", i, nwpm->tstats[0].avg[i]);
+	}
+}
+
+/*
+ * nss_wifi_log_verbose()
+ *	Log message contents.
+ */
+static void nss_wifi_log_verbose(struct nss_wifi_msg *ncm)
+{
+	switch (ncm->cm.type) {
+	case NSS_WIFI_INIT_MSG:
+		nss_wifi_log_init_msg(ncm);
+		break;
+
+	case NSS_WIFI_HTT_INIT_MSG:
+		nss_wifi_log_htt_init_msg(ncm);
+		break;
+
+	case NSS_WIFI_TX_INIT_MSG:
+		nss_wifi_log_tx_init_msg(ncm);
+		break;
+
+	case NSS_WIFI_RAW_SEND_MSG:
+		nss_wifi_log_rawsend_msg(ncm);
+		break;
+
+	case NSS_WIFI_MGMT_SEND_MSG:
+		nss_wifi_log_mgmtsend_msg(ncm);
+		break;
+
+	case NSS_WIFI_WDS_PEER_ADD_MSG:
+		nss_wifi_log_wds_peer_msg(ncm);
+		break;
+
+	case NSS_WIFI_WDS_PEER_DEL_MSG:
+		nss_wifi_log_wds_peer_msg(ncm);
+		break;
+
+	case NSS_WIFI_STOP_MSG:
+		nss_wifi_log_stop_msg(ncm);
+		break;
+
+	case NSS_WIFI_RESET_MSG:
+		nss_wifi_log_reset_msg(ncm);
+		break;
+
+	case NSS_WIFI_PEER_FREELIST_APPEND_MSG:
+		nss_wifi_log_peer_freelist_append_msg(ncm);
+		break;
+
+	case NSS_WIFI_RX_REORDER_ARRAY_FREELIST_APPEND_MSG:
+		nss_wifi_log_rx_reorder_array_freelist_append_msg(ncm);
+		break;
+
+	case NSS_WIFI_MONITOR_FILTER_SET_MSG:
+		nss_wifi_log_set_filter_msg(ncm);
+		break;
+
+	case NSS_WIFI_PEER_BS_STATE_MSG:
+		nss_wifi_log_peer_activity_msg(ncm);
+		break;
+
+	case NSS_WIFI_RX_VOW_EXTSTATS_SET_MSG:
+		nss_wifi_log_rx_vow_extstats_set_msg(ncm);
+		break;
+
+	case NSS_WIFI_PKTLOG_CFG_MSG:
+		nss_wifi_log_pktlog_cfg_msg(ncm);
+		break;
+
+	case NSS_WIFI_ENABLE_PERPKT_TXSTATS_MSG:
+		nss_wifi_log_enable_perpkt_txstats_msg(ncm);
+		break;
+
+	case NSS_WIFI_IGMP_MLD_TOS_OVERRIDE_MSG:
+		nss_wifi_log_override_tos_msg(ncm);
+		break;
+
+	case NSS_WIFI_OL_STATS_CFG_MSG:
+		nss_wifi_log_ol_stats_cfg_msg(ncm);
+		break;
+
+	case NSS_WIFI_TX_QUEUE_CFG_MSG:
+		nss_wifi_log_tx_queue_cfg_msg(ncm);
+		break;
+
+	case NSS_WIFI_TX_MIN_THRESHOLD_CFG_MSG:
+		nss_wifi_log_tx_min_threshold_cfg(ncm);
+		break;
+
+	case NSS_WIFI_DBDC_PROCESS_ENABLE_MSG:
+		nss_wifi_log_dbdc_process_enable_msg(ncm);
+		break;
+
+	case NSS_WIFI_PRIMARY_RADIO_SET_MSG:
+		nss_wifi_log_primary_radio_set_msg(ncm);
+		break;
+
+	case NSS_WIFI_FORCE_CLIENT_MCAST_TRAFFIC_SET_MSG:
+		nss_wifi_log_force_client_mcast_traffic_set_msg(ncm);
+		break;
+
+	case NSS_WIFI_STORE_OTHER_PDEV_STAVAP_MSG:
+		nss_wifi_log_store_other_pdev_stavap_msg(ncm);
+		break;
+
+	case NSS_WIFI_STA_KICKOUT_MSG:
+		nss_wifi_log_sta_kickout_msg(ncm);
+		break;
+
+	case NSS_WIFI_WNM_PEER_RX_ACTIVITY_MSG:
+		nss_wifi_log_wnm_peer_rx_activity(ncm);
+		break;
+
+	case NSS_WIFI_WDS_VENDOR_MSG:
+		nss_wifi_log_wds_extn_peer_cfg_msg(ncm);
+		break;
+
+	case NSS_WIFI_TX_CAPTURE_SET_MSG:
+		nss_wifi_log_tx_capture_msg(ncm);
+		break;
+
+	case NSS_WIFI_ALWAYS_PRIMARY_SET_MSG:
+		nss_wifi_log_always_primary_set_msg(ncm);
+		break;
+
+	case NSS_WIFI_CMD_MSG:
+		nss_wifi_log_cmd_msg(ncm);
+		break;
+
+	case NSS_WIFI_ENABLE_OL_STATSV2_MSG:
+		nss_wifi_log_enable_ol_statsv2_msg(ncm);
+		break;
+
+	case NSS_WIFI_OL_PEER_TIME_MSG:
+		nss_wifi_log_enable_ol_peer_time_msg(ncm);
+		break;
+
+	case NSS_WIFI_FLUSH_HTT_CMD_MSG:
+	case NSS_WIFI_OL_STATS_MSG:
+	case NSS_WIFI_MSDU_TTL_SET_MSG:
+	case NSS_WIFI_PEER_STATS_MSG:
+	case NSS_WIFI_FW_STATS_MSG:
+	case NSS_WIFI_SEND_RRA_MEMORY_REQUEST_MSG:
+	case NSS_WIFI_STATS_MSG:
+	case NSS_WIFI_POST_RECV_MSG:
+	case NSS_WIFI_SEND_PEER_MEMORY_REQUEST_MSG:
+		/*
+		 * No log for these valid messages.
+		 */
+		break;
+
+	default:
+		nss_warning("%p: Invalid message type\n", ncm);
+		break;
+	}
+}
+
+/*
+ * nss_wifi_log_tx_msg()
+ *	Log messages transmitted to FW.
+ */
+void nss_wifi_log_tx_msg(struct nss_wifi_msg *ncm)
+{
+	if (ncm->cm.type >= NSS_WIFI_MAX_MSG) {
+		nss_warning("%p: Invalid message type\n", ncm);
+		return;
+	}
+
+	nss_info("%p: type[%d]:%s\n", ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type]);
+	nss_wifi_log_verbose(ncm);
+}
+
+/*
+ * nss_wifi_log_rx_msg()
+ *	Log messages received from FW.
+ */
+void nss_wifi_log_rx_msg(struct nss_wifi_msg *ncm)
+{
+	if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) {
+		nss_warning("%p: Invalid response\n", ncm);
+		return;
+	}
+
+	if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) {
+		nss_info("%p: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type,
+			nss_wifi_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response]);
+		goto verbose;
+	}
+
+	if (ncm->cm.error >= NSS_WIFI_EMSG_MAX) {
+		nss_warning("%p: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n",
+			ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type],
+			ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+			ncm->cm.error);
+		goto verbose;
+	}
+
+	nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n",
+		ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type],
+		ncm->cm.response, nss_cmn_response_str[ncm->cm.response],
+		ncm->cm.error, nss_wifi_log_error_response_types_str[ncm->cm.error]);
+
+verbose:
+	nss_wifi_log_verbose(ncm);
+}
diff --git a/nss_wifi_log.h b/nss_wifi_log.h
new file mode 100644
index 0000000..c47a62b
--- /dev/null
+++ b/nss_wifi_log.h
@@ -0,0 +1,37 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_WIFI_LOG_H__
+#define __NSS_WIFI_LOG_H__
+
+/*
+ * nss_WIFI_log.h
+ *	NSS WIFI Log Header File
+ */
+
+/*
+ * nss_WIFI_log_tx_msg
+ *	Logs a WIFI message that is sent to the NSS firmware.
+ */
+void nss_wifi_log_tx_msg(struct nss_wifi_msg *ncm);
+
+/*
+ * nss_WIFI_log_rx_msg
+ *	Logs a WIFI message that is received from the NSS firmware.
+ */
+void nss_wifi_log_rx_msg(struct nss_wifi_msg *ncm);
+
+#endif /* __NSS_WIFI_LOG_H__ */