Merge "[qca-nss-drv] Wi-Fi Log"
diff --git a/Makefile b/Makefile
index 0a9f3f1..c769de7 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,6 +105,7 @@
 			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 \
@@ -128,7 +131,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 8f8bb9c..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 \
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_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 */